diff --git a/include/comms.h b/include/comms.h index 5eb1088..84723a8 100644 --- a/include/comms.h +++ b/include/comms.h @@ -3,7 +3,7 @@ #include "globals.h" #include "nonvolatile.h" #include -#include "main.h" +#include "core.h" void Communication(); void XDRGTKRoutine(); diff --git a/include/core.h b/include/core.h new file mode 100644 index 0000000..d0c94d4 --- /dev/null +++ b/include/core.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include + +void tftPrint(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, uint8_t fontsize); +void tftPrint16(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, bool force_font = true, bool font = false); +void tftReplace(int8_t offset, const String & textold, const String & text, int16_t x, int16_t y, int color, int smoothcolor, int background, uint8_t fontsize); +void tftReplace16(int8_t offset, const String & textold, const String & text, int16_t x, int16_t y, int color, int smoothcolor, int background, bool force_font = true, bool font = false); +const char* textUI(uint16_t number); +uint8_t doAutoMemory(uint16_t startfreq, uint16_t stopfreq, uint8_t startmem, uint8_t stopmem, bool rdsonly, uint8_t doublepi); +void showAutoSquelch(bool mode); +void UpdateFonts(); +void setAutoSpeedSPI(); +void DoMemoryPosTune(); +void startFMDXScan(); +void endMenu(); +void TuneUp(); +void ShowStepSize(); +void ShowFreq(int mode); +void ShowMemoryPos(); +void TuneDown(); +void ShowTuneMode(); +void SelectBand(); +void doBW(); +void ModeButtonPress(); +void updateEQ(); +void updateiMS(); +void Seek(bool mode); +void MuteScreen(bool setting); +void cancelDXScan(); +void doStereoToggle(); +void updateBW(); +void ShowRDSLogo(bool RDSstatus); +void DataPrint(String string); diff --git a/include/gui.h b/include/gui.h index 99e9d6f..97a6956 100644 --- a/include/gui.h +++ b/include/gui.h @@ -3,13 +3,13 @@ #include "globals.h" #include "utils.h" #include "menugraphics.h" -#include "main.h" +#include "core.h" static const char* const unitString[] = {"dBμV", "dBf", "dBm"}; static const char* const FreqFont[] = {"Classic", "Roubenstil", "Motoya", "Aura2", "Comic", "Modern"}; static const char* const Theme[] = {"Essence", "Cyan", "Crimson", "Monochrome", "Volcano", "Dendro", "Sakura", "Whiteout", "Tangerine", "Ocean", "Indigo", "Queer", "GoldBrite", "Bubblegum"}; -static const char* BWButtonLabelsFM[] = {"56 kHz", "64 kHz", "72 kHz", "84 kHz", "97 kHz", "114 kHz", "133 kHz", "151 kHz", "168 kHz", "184 kHz", "200 kHz", "217 kHz", "236 kHz", "254 kHz", "287 kHz", "311 kHz", "Auto", "iMS", "EQ"}; -static const char* BWButtonLabelsAM[] = {"3 kHz", "4 kHz", "6 kHz", "8 kHz"}; +extern const char* BWButtonLabelsFM[]; +extern const char* BWButtonLabelsAM[]; void BuildAFScreen(); void BuildRDSStatScreen(); diff --git a/include/logbook.h b/include/logbook.h index 5f60a79..dc40076 100644 --- a/include/logbook.h +++ b/include/logbook.h @@ -6,7 +6,7 @@ using fs::FS; #include #include "globals.h" #include "rtc.hpp" -#include "main.h" +#include "core.h" void handleRoot(); void handleDownloadCSV(); diff --git a/include/main.h b/include/main.h index fd1bb56..d9d8637 100644 --- a/include/main.h +++ b/include/main.h @@ -1,33 +1,16 @@ #pragma once -#include -#include -void tftPrint(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, uint8_t fontsize); -void tftPrint16(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, bool force_font = true, bool font = false); -void tftReplace(int8_t offset, const String & textold, const String & text, int16_t x, int16_t y, int color, int smoothcolor, int background, uint8_t fontsize); -const char* textUI(uint16_t number); -uint8_t doAutoMemory(uint16_t startfreq, uint16_t stopfreq, uint8_t startmem, uint8_t stopmem, bool rdsonly, uint8_t doublepi); -void showAutoSquelch(bool mode); -void UpdateFonts(); -void setAutoSpeedSPI(); -void DoMemoryPosTune(); -void startFMDXScan(); -void endMenu(); -void TuneUp(); -void ShowStepSize(); -void ShowFreq(int mode); -void ShowMemoryPos(); -void TuneDown(); -void ShowTuneMode(); -void SelectBand(); -void doBW(); -void ModeButtonPress(); -void updateEQ(); -void updateiMS(); -void Seek(bool mode); -void MuteScreen(bool setting); -void cancelDXScan(); -void doStereoToggle(); -void updateBW(); -void ShowRDSLogo(bool RDSstatus); -void DataPrint(String string); +#include "system_console.h" +#include "globals.h" + +extern Console console; +extern RTC_DATA_ATTR bool gpio_chip; +extern RTC_DATA_ATTR bool tef_found; + +template +void panic(Args... args); + +void Round30K(unsigned int freq); +void Round50K(unsigned int freq); +void Round100K(unsigned int freq); +void Round200K(unsigned int freq); diff --git a/include/rds.h b/include/rds.h index 1a1b75e..0250f3d 100644 --- a/include/rds.h +++ b/include/rds.h @@ -8,7 +8,7 @@ #include "globals.h" #include "NTPupdate.h" #include "rtc.hpp" -#include "main.h" +#include "core.h" void ShowAdvancedRDS(); void readRds(); diff --git a/src/NTPupdate.cpp b/src/NTPupdate.cpp index a2c2939..77c22ce 100644 --- a/src/NTPupdate.cpp +++ b/src/NTPupdate.cpp @@ -1,7 +1,7 @@ #include "NTPupdate.h" void sendNTPpacket(IPAddress &address) { - byte packetBuffer[NTP_PACKET_SIZE] = {0}; // Initialize buffer with zeros + byte packetBuffer[NTP_PACKET_SIZE] = {0}; packetBuffer[0] = 0b11100011; // LI, Version, Mode packetBuffer[2] = 6; // Polling interval @@ -32,11 +32,7 @@ time_t getNtpTime() { if (Udp.parsePacket() >= NTP_PACKET_SIZE) { Udp.read(packetBuffer, NTP_PACKET_SIZE); - unsigned long secsSince1900 = - ((unsigned long)packetBuffer[40] << 24) | - ((unsigned long)packetBuffer[41] << 16) | - ((unsigned long)packetBuffer[42] << 8) | - (unsigned long)packetBuffer[43]; + unsigned long secsSince1900 = ((unsigned long)packetBuffer[40] << 24) | ((unsigned long)packetBuffer[41] << 16) | ((unsigned long)packetBuffer[42] << 8) | (unsigned long)packetBuffer[43]; return secsSince1900 - 2208988800UL; } diff --git a/src/Tuner_Interface.cpp b/src/Tuner_Interface.cpp index a18383e..2d98fa3 100644 --- a/src/Tuner_Interface.cpp +++ b/src/Tuner_Interface.cpp @@ -16,8 +16,7 @@ bool Tuner_ReadBuffer(unsigned char *buf, uint16_t len) { if (Wire.available() >= len) { for (uint16_t i = 0; i < len; i++) buf[i] = Wire.read(); return true; - } - return false; + } return false; } static void Tuner_Patch_Load(const unsigned char *pLutBytes, uint16_t size) { diff --git a/src/core.cpp b/src/core.cpp new file mode 100644 index 0000000..3444d2f --- /dev/null +++ b/src/core.cpp @@ -0,0 +1,3624 @@ +#include "soc/soc.h" +#include "soc/rtc_cntl_reg.h" +#include +#include +#include +using fs::FS; +#include +#include "NTPupdate.h" +#include "globals.h" +#include "gui.h" +#include "comms.h" +#include "rds.h" +#include "touch.h" +#include "nonvolatile.h" +#include "utils.h" +#include "system_console.h" +#include "core.h" + +Console console(&tft); +RTC_DATA_ATTR bool gpio_chip = false; +RTC_DATA_ATTR bool tef_found = false; + +template +void panic(Args... args) { + radio.power(1); + tft.fillScreen(TFT_RED); + console.reset(); + + (console.print(args), ...); + while (true); +} + +#pragma region helpers +inline bool isSignalQualityGood(int usn, int wam, int ostatus, int threshold_multiplier = SCAN_SIGNAL_THRESHOLD_USN_MULTIPLIER, int ostatus_threshold = SCAN_SIGNAL_THRESHOLD_OSTATUS) { + return (usn < fmscansens * threshold_multiplier) && + (wam < SCAN_SIGNAL_THRESHOLD_WAM) && + (ostatus < ostatus_threshold) && + (ostatus > -ostatus_threshold); +} + +void Round30K(unsigned int freq) { + if (freq % FREQ_OIRT_STEP_30K == 1) frequency_OIRT = (freq + 1); + else if (freq % FREQ_OIRT_STEP_30K == 0) frequency_OIRT = (freq - 1); +} + +void Round50K(unsigned int freq) { + if (freq % 10 < 3) frequency = (freq - freq % 10); + else if (freq % 10 > 2 && freq % 10 < 8) frequency = (freq - (freq % 10 - 5)); + else if (freq % 10 > 7) frequency = (freq - (freq % 10) + 10); +} + +void Round100K(unsigned int freq) { + if (freq % 10 < 5) frequency = (freq - freq % 10); + else frequency = (freq - (freq % 10) + 10); +} + +void Round200K(unsigned int freq) { + frequency = (freq / 10) * 10; + + if (freq % 10 >= 5) frequency += 10; + if ((frequency / 100) % 2 == 0) frequency += 10; + if (frequency > 10800) frequency = 10790; + if (frequency % 20 == 0 && (frequency / 10) % 2 == 0) frequency -= 10; +} + +void Round5K(unsigned int freqAM) { + if (freqAM % 10 < 3) frequency_AM = (freqAM - freqAM % 10); + else if (freqAM % 10 > 2 && freqAM % 10 < 8) frequency_AM = (freqAM - (freqAM % 10 - 5)); + else if (freqAM % 10 > 7) frequency_AM = (freqAM - (freqAM % 10) + 10); +} + +inline void deepSleep() { + MuteScreen(1); + StoreFrequency(); + radio.power(1); + esp_sleep_enable_ext0_wakeup((gpio_num_t)ROTARY_PIN_A, LOW); + esp_deep_sleep_start(); +} + +inline bool IsStationEmpty() { + return presets[memorypos].band == BAND_FM && presets[memorypos].frequency == EE_PRESETS_FREQUENCY; +} + +void ShowFreq(int mode); +void doLog() { + if (!autologged && RDSstatus && radio.rds.correctPI != 0) { + if (autolog) { + switch (addRowToCSV()) { + case 0: ShowFreq(2); break; + case 1: ShowFreq(3); break; + case 2: ShowFreq(4); break; + } + + delay(DELAY_UI_UPDATE_MS); + ShowFreq(0); + } + autologged = true; + } +} + +inline void EdgeBeeper() { + if(!edgebeep) return; + radio.tone(50, -5, 2000); +} + +const char* textUI(uint16_t number) { + if (number >= language_entrynumber) return "Overflow"; + else return (const char*)pgm_read_ptr(&(myLanguage[language][number])); +} + +inline bool shouldHighlightBWButton(byte temp, byte set) { + return (set == temp) || (temp == 17 && set == 0) || (temp == 18 && !iMSset) || (temp == 19 && !EQset); +} + +inline const char* getBWButtonLabel(byte temp, bool isFM) { + constexpr byte BW_OK_BUTTON = 20; + if (temp == BW_OK_BUTTON) return "OK"; + return isFM ? BWButtonLabelsFM[temp - 1] : BWButtonLabelsAM[temp - 1]; +} + +void doBWtuneUp() { + rotary = 0; + constexpr byte BW_OK_BUTTON = 20; + constexpr byte BW_AM_MAX = 4; + + if (band < BAND_GAP) { + // FM band + drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), false); + BWsettemp++; + if (BWsettemp > BW_OK_BUTTON) BWsettemp = 1; + drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), true); + } else { + // AM band + drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), false); + BWsettemp++; + if (BWsettemp > BW_AM_MAX && BWsettemp < BW_OK_BUTTON) BWsettemp = BW_OK_BUTTON; + else if (BWsettemp > BW_OK_BUTTON) BWsettemp = 1; + drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), true); + } +} + +void doBWtuneDown() { + rotary = 0; + constexpr byte BW_OK_BUTTON = 20; + constexpr byte BW_AM_MAX = 4; + + if (band < BAND_GAP) { + // FM band + drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), false); + BWsettemp--; + if (BWsettemp > BW_OK_BUTTON || BWsettemp == 0) BWsettemp = BW_OK_BUTTON; + drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), true); + } else { + // AM band + drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), false); + BWsettemp--; + if (BWsettemp > BW_AM_MAX && BWsettemp < BW_OK_BUTTON) BWsettemp = BW_AM_MAX; + else if (BWsettemp == 0) BWsettemp = BW_OK_BUTTON; + drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), true); + } +} + +void ShowStereoStatus() { + if (StereoToggle) { + if (band < BAND_GAP) Stereostatus = radio.getStereoStatus(); else Stereostatus = false; + if (Stereostatus != Stereostatusold) { + if (Stereostatus && !screenmute) tft.drawBitmap(STEREO_ICON_X, STEREO_ICON_Y, Stereo, 32, 22, StereoColor); + else if (!screenmute) tft.drawBitmap(STEREO_ICON_X, STEREO_ICON_Y, Stereo, 32, 22, GreyoutColor); + Stereostatusold = Stereostatus; + } + } +} + +void ShowRSSI() { + if (wifi) rssi = WiFi.RSSI(); else rssi = 0; + if (rssiold != rssi) { + if (!wifi && batterydetect) tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, BackgroundColor); + else if (rssi == 0) tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); + else if (rssi > -50 && rssi < 0) tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorHigh); + else if (rssi > -60) { + tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); + tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi3, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorHigh); + } else if (rssi > -70) { + tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); + tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi2, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorLow); + } else if (rssi < -70) { + tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); + tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi1, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorLow); + } + rssiold = rssi; + } +} + +void ShowBW() { + if (!BWtune && millis() >= bwupdatetimer + TIMER_BW_TIMER) bwupdatetimer = millis(); + else if(!BWtune) return; + + if (BW != BWOld || BWreset) { + if(BW == 0) panic("BW is 0"); + else if(BW > 311) panic("BW larger than 311"); + + if(BWset == 0) tftReplace(ARIGHT, String(BWOld, DEC), String(BW, DEC), 203, 4, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 28); else tftReplace(ARIGHT, String (BWOld, DEC), String(BW, DEC), 203, 4, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 28); + BWOld = BW; + BWreset = false; + if (wifi) { + Udp.beginPacket(remoteip, 9030); + Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";bandwidth=" + String(BW * 1000)); + Udp.endPacket(); + } + } +} + +void updateSWMIBand() { + switch (SWMIBandPos) { + case SW_MI_BAND_11M: + case SW_MI_BAND_13M: + case SW_MI_BAND_15M: + case SW_MI_BAND_16M: + case SW_MI_BAND_19M: + case SW_MI_BAND_22M: + case SW_MI_BAND_25M: + case SW_MI_BAND_31M: + case SW_MI_BAND_41M: + case SW_MI_BAND_49M: + case SW_MI_BAND_60M: + case SW_MI_BAND_75M: + case SW_MI_BAND_90M: + case SW_MI_BAND_120M: + case SW_MI_BAND_160M: + FrequencySprite.drawString(SWMIBandstring + " ", 0, 0, 6); + beepresetstart = true; + if (beepresetstop) { + EdgeBeeper(); + beepresetstop = false; + } + break; + + case SW_MI_BAND_GAP: + beepresetstop = true; + if (beepresetstart) { + EdgeBeeper(); + beepresetstart = false; + } + break; + } +} + +inline void updateCodetect() { + if (band > BAND_GAP) { + if (WAM) tftPrint16(ALEFT, "CO", 50, 61, PrimaryColor, PrimaryColorSmooth); + else tftPrint16(ALEFT, "CO", 50, 61, BackgroundColor, BackgroundColor); + } +} + +void ShowSignalLevel(); +void ShowOffset(); +void ShowBattery(); +void GetData() { + if (!afscreen && !rdsstatscreen) ShowSignalLevel(); + if (!BWtune && !menu && !rdsstatscreen) showPS(); + + if (band < BAND_GAP && !BWtune && !menu) { + if (advancedRDS && !afscreen && !rdsstatscreen && !screenmute) ShowAdvancedRDS(); + if (!advancedRDS && !afscreen && rdsstatscreen && !screenmute) ShowRDSStatistics(); + if (afscreen && !screenmute) ShowAFEON(); + if (!afscreen && !rdsstatscreen) { + if (!screenmute) ShowErrors(); + showPTY(); + showRadioText(); + if (millis() >= tuningtimer + 200) doAF(); + } + showPI(); + } + + ShowStereoStatus(); + + if (!screenmute) { + showCT(); + ShowRSSI(); + ShowOffset(); + ShowBW(); + updateCodetect(); + if (millis() >= tuningtimer + 200 && !wifi) ShowBattery(); + } +} + +void WakeToSleep(bool yes) { + if (yes) { + screensavertriggered = true; + switch (poweroptions) { + case LCD_OFF: + MuteScreen(1); + break; + case LCD_BRIGHTNESS_1_PERCENT: + analogWrite(CONTRASTPIN, map(ContrastSet / 100, 0, 100, 0, 255)); + break; + case LCD_BRIGHTNESS_A_QUARTER: + analogWrite(CONTRASTPIN, map(ContrastSet / 4, 0, 100, 0, 255)); + break; + case LCD_BRIGHTNESS_HALF: + analogWrite(CONTRASTPIN, map(ContrastSet / 2, 0, 100, 0, 255)); + break; + } + } else { + switch (poweroptions) { + case LCD_OFF: + MuteScreen(0); + screensavertriggered = false; + screensavertimer = millis(); + break; + case LCD_BRIGHTNESS_1_PERCENT: + case LCD_BRIGHTNESS_A_QUARTER: + case LCD_BRIGHTNESS_HALF: + MuteScreen(0); + screensavertriggered = false; + screensavertimer = millis(); + break; + } + analogWrite(CONTRASTPIN, map(ContrastSet, 0, 100, 0, 255)); + } +} + +void CheckBandForbiddenFM() { + switch (band) { + case BAND_FM: + if (bandFM == FM_BAND_OIRT) bandforbidden = 1; else bandforbidden = 0; + break; + case BAND_OIRT: + if (bandFM == FM_BAND_FM) bandforbidden = 1; else bandforbidden = 0; + break; + } +} + +void CheckBandForbiddenAM() { + switch (band) { + case BAND_LW: + if (bandAM == AM_BAND_MW_SW || bandAM == AM_BAND_MW || bandAM == AM_BAND_SW) bandforbidden = 1; + else bandforbidden = 0; + break; + case BAND_MW: + if (bandAM == AM_BAND_LW_SW || bandAM == AM_BAND_LW || bandAM == AM_BAND_SW) bandforbidden = 1; + else bandforbidden = 0; + break; + case BAND_SW: + if (bandAM == AM_BAND_LW_MW || bandAM == AM_BAND_LW || bandAM == AM_BAND_MW) bandforbidden = 1; + else bandforbidden = 0; + break; + } +} + +void FMjumptoAM() { + if (bandAM == AM_BAND_ALL || bandAM == AM_BAND_LW_MW || bandAM == AM_BAND_LW_SW || bandAM == AM_BAND_LW) { + band = BAND_LW; + if (stepsize > 3) stepsize = 3; + } else if (bandAM == AM_BAND_MW_SW || bandAM == AM_BAND_MW) band = BAND_MW; + else if (bandAM == AM_BAND_SW) band = BAND_SW; +} + +void AMjumptoFM() { + if (bandFM != FM_BAND_NONE) { + if (bandFM == FM_BAND_FM) band = BAND_FM; else band = BAND_OIRT; + } else FMjumptoAM(); +} + +void ToggleBand(byte nowBand) { + switch (nowBand) { + case BAND_LW: + if (bandAM == AM_BAND_LW_MW || bandAM == AM_BAND_ALL) band = BAND_MW; + else if (bandAM == AM_BAND_LW_SW) band = BAND_SW; + else if (bandAM == AM_BAND_LW || bandAM == AM_BAND_NONE) AMjumptoFM(); + break; + case BAND_MW: + if (bandAM == AM_BAND_MW_SW || bandAM == AM_BAND_ALL) { + band = BAND_SW; + } else if (bandAM == AM_BAND_LW_MW) { + if (bandFM != FM_BAND_NONE) { + if (bandFM == FM_BAND_FM) band = BAND_FM; else band = BAND_OIRT; + } else band = BAND_LW; + } else if (bandAM == AM_BAND_MW || bandAM == AM_BAND_NONE) AMjumptoFM(); + break; + case BAND_SW: + if (bandFM != FM_BAND_NONE) { + if (bandFM == FM_BAND_FM) band = BAND_FM; + else band = BAND_OIRT; + } else { + if (bandAM == AM_BAND_LW_SW || bandAM == AM_BAND_ALL) band = BAND_LW; + else if (bandAM == AM_BAND_MW_SW) band = BAND_MW; + else if (bandAM == AM_BAND_SW || bandAM == AM_BAND_NONE) AMjumptoFM(); + } + break; + case BAND_OIRT: + if(bandFM == FM_BAND_ALL || bandFM == FM_BAND_FM) band = BAND_FM; + else if(bandFM == FM_BAND_OIRT && bandAM != AM_BAND_NONE) FMjumptoAM(); + break; + case BAND_FM: + if (bandAM != AM_BAND_NONE) FMjumptoAM(); + else if (bandFM == FM_BAND_OIRT || bandFM == FM_BAND_ALL) band = BAND_OIRT; + break; + } +} + +void doBandSelectionFM() { + if (band > BAND_GAP) return; + + switch (bandFM) { + case FM_BAND_ALL: + break; + case FM_BAND_OIRT: + if (band == BAND_FM) { + band = BAND_OIRT; + if (frequency_OIRT > FREQ_FM_OIRT_END) { + frequency_OIRT = FREQ_FM_OIRT_START; + EdgeBeeper(); + } else if (frequency_OIRT < FREQ_FM_OIRT_START) { + frequency_OIRT = FREQ_FM_OIRT_END; + EdgeBeeper(); + } + SelectBand(); + } + break; + case FM_BAND_FM: + if (band == BAND_OIRT) { + band = BAND_FM; + if (frequency > HighEdgeSet * 10) { + frequency = LowEdgeSet * 10; + EdgeBeeper(); + } else if (frequency < LowEdgeSet * 10) { + frequency = HighEdgeSet * 10; + EdgeBeeper(); + } SelectBand(); + } + break; + case FM_BAND_NONE: + ToggleBand(band); + SelectBand(); + break; + } +} + +void doBandSelectionAM() { + if (band < BAND_GAP) return; + + switch (bandAM) { + case AM_BAND_ALL: break; + case AM_BAND_LW_MW: + if (band == BAND_SW) { + band = BAND_LW; + SelectBand(); + } break; + case AM_BAND_LW_SW: + if (band == BAND_MW) { + band = BAND_LW; + SelectBand(); + } break; + case AM_BAND_MW_SW: + if (band == BAND_LW) { + band = BAND_MW; + SelectBand(); + } break; + case AM_BAND_LW: + if (band != BAND_LW) { + band = BAND_LW; + SelectBand(); + } break; + case AM_BAND_MW: + if (band != BAND_MW) { + band = BAND_MW; + SelectBand(); + } break; + case AM_BAND_SW: + if (band != BAND_SW) { + band = BAND_SW; + SelectBand(); + } break; + case AM_BAND_NONE: + ToggleBand(band); + SelectBand(); + break; + } +} + +void BANDBUTTONPress() { + if(seek)radio.setUnMute(); + seek = false; + if (scandxmode) { + ShowFreq(5); + ShowFreq(0); + } else { + if (memorystore) { + EEPROM.writeByte(memorypos + EE_PRESETS_BAND_START, BAND_FM); + EEPROM.writeUInt((memorypos * 4) + EE_PRESETS_FREQUENCY_START, EE_PRESETS_FREQUENCY); + EEPROM.commit(); + presets[memorypos].band = BAND_FM; + presets[memorypos].frequency = EE_PRESETS_FREQUENCY; + memorystore = false; + ShowTuneMode(); + if (memoryposstatus == MEM_DARK || memoryposstatus == MEM_EXIST) { + memoryposstatus = MEM_NORMAL; + ShowMemoryPos(); + } + } else { + if (!usesquelch) radio.setUnMute(); + unsigned long counterold = millis(); + unsigned long counter = millis(); + if (!BWtune && !menu) { + while (digitalRead(BANDBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); + + if (counter - counterold < 1000) { + if (afscreen || rdsstatscreen) { + leave = true; + BuildAdvancedRDS(); + freq_in = 0; + } else if (advancedRDS) { + leave = true; + BuildDisplay(); + freq_in = 0; + SelectBand(); + screensavertimer = millis(); + } else doBandToggle(); + } else { + if (band < BAND_GAP) { + if (advancedRDS && !seek) { + BuildAFScreen(); + freq_in = 0; + } else { + BuildAdvancedRDS(); + freq_in = 0; + } + } else WakeToSleep(true); + while (digitalRead(BANDBUTTON) == LOW && counter - counterold <= 2500) counter = millis(); + if (counter - counterold > 2499) { + switch (longbandpress) { + case STANDBY: + deepSleep(); + break; + case SCREENOFF: + screensavertriggered = true; + MuteScreen(1); + break; + } + } + } + } + } + } + while (digitalRead(BANDBUTTON) == LOW) delay(DELAY_BUTTON_DEBOUNCE_MS); + delay(DELAY_BUTTON_DEBOUNCE_EXTRA_MS); +} + +void LimitAMFrequency() { + switch (band) { + case BAND_LW: + frequency_AM = frequency_LW; + if (frequency_AM > LWHighEdgeSet || frequency_AM < LWLowEdgeSet) frequency_AM = LWLowEdgeSet; + break; + case BAND_MW: + frequency_AM = frequency_MW; + if (frequency_AM > MWHighEdgeSet || frequency_AM < MWLowEdgeSet) frequency_AM = MWLowEdgeSet; + break; + case BAND_SW: + frequency_AM = frequency_SW; + if (frequency_AM > SWHighEdgeSet || frequency_AM < SWLowEdgeSet) frequency_AM = SWLowEdgeSet; + break; + } +} + +void BWButtonPress() { + if (seek) radio.setUnMute(); + seek = false; + if (afscreen || rdsstatscreen) BuildRDSStatScreen(); + else { + if (scandxmode) { + unsigned long counterold = millis(); + unsigned long counter = millis(); + while (digitalRead(BWBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); + + if (counter - counterold < 1000) { + ShowFreq(5); + ShowFreq(0); + } else cancelDXScan(); + } else { + if (!usesquelch) radio.setUnMute(); + if (!BWtune && !menu) { + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + unsigned long counterold = millis(); + unsigned long counter = millis(); + while (digitalRead(BWBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); + + if (counter - counterold < 1000) { + BuildBWSelector(); + freq_in = 0; + BWtune = true; + BWtemp = BWset; + } else { + if (band == BAND_FM || band == BAND_OIRT) doStereoToggle(); + else { + BuildBWSelector(); + freq_in = 0; + BWtune = true; + } + } + } + } + } + while (digitalRead(BWBUTTON) == LOW) delay(DELAY_BUTTON_DEBOUNCE_MS); + delay(DELAY_BUTTON_DEBOUNCE_EXTRA_MS); +} + +void doStereoToggle() { + if (StereoToggle) { + if (!screenmute) { + tft.drawBitmap(32, 5, Stereo, 32, 22, BackgroundColor); + tft.drawBitmap(38, 5, Mono, 22, 22, SecondaryColor); + } + radio.setMono(true); + StereoToggle = false; + } else { + if (!screenmute) { + tft.drawBitmap(38, 5, Mono, 22, 22, BackgroundColor); + tft.drawBitmap(32, 5, Stereo, 32, 22, GreyoutColor); + } + radio.setMono(false); + Stereostatusold = false; + StereoToggle = true; + } + radio.setAudio(audiomode); + EEPROM.writeByte(EE_BYTE_AUDIOMODE, audiomode); + EEPROM.writeByte(EE_BYTE_STEREO, StereoToggle); + EEPROM.commit(); +} + +void ShowStepSize() { + if (!advancedRDS) { + tft.fillRect(191, 38, 15, 4, GreyoutColor); + tft.fillRect(222, 38, 15, 4, GreyoutColor); + if (band < BAND_GAP) tft.fillRect(113, 38, 15, 4, GreyoutColor); else if (band != BAND_LW && band != BAND_MW) tft.fillRect(129, 38, 15, 4, GreyoutColor); + if (band < BAND_GAP) tft.fillRect(144, 38, 15, 4, GreyoutColor); else tft.fillRect(159, 38, 15, 4, GreyoutColor); + if (stepsize == 1) tft.fillRect(222, 38, 15, 4, InsignificantColor); + if (stepsize == 2) tft.fillRect(191, 38, 15, 4, InsignificantColor); + if (stepsize == 3) { + if (band < BAND_GAP) tft.fillRect(144, 38, 15, 4, InsignificantColor); else tft.fillRect(159, 38, 15, 4, InsignificantColor); + } + if (stepsize == 4) { + if (band < BAND_GAP) tft.fillRect(113, 38, 15, 4, InsignificantColor); else tft.fillRect(129, 38, 15, 4, InsignificantColor); + } + } +} + +bool IsFrequencyUsed(unsigned int freq) { + bool result = false; + for (byte x = scanstart; x <= scanstop; x++) { + if ((presets[x].band == BAND_FM || presets[x].band == BAND_OIRT) && presets[x].frequency == freq) { + result = true; + break; + } + } + return result; +} + +void ShowRDSLogo(bool RDSstatus) { + if (screenmute) return; + if (RDSstatus != RDSstatusold) { + if (RDSstatus) tft.drawBitmap(68, 5, RDSLogo, 35, 22, RDSColor); + else tft.drawBitmap(68, 5, RDSLogo, 35, 22, GreyoutColor); + } + RDSstatusold = RDSstatus; +} + +void showAutoSquelch(bool mode) { + if (screenmute) return; + if (mode) tft.drawBitmap(223, 147, AutoSQ, 18, 18, PrimaryColor); + else tft.drawBitmap(223, 147, AutoSQ, 18, 18, BackgroundColor); +} + +void updateBW() { + if (BWset == 0) { + if (!BWtune && !screenmute && !advancedRDS && !afscreen && !rdsstatscreen) { + tft.fillRoundRect(248, 36, 69, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "AUTO BW", 282, 38, BackgroundColor, SecondaryColor); + } + radio.setFMABandw(); + } else { + if (!BWtune && !screenmute && !advancedRDS && !afscreen && !rdsstatscreen) { + tft.fillRoundRect(248, 36, 69, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "AUTO BW", 282, 38, BackgroundColor, GreyoutColor); + } + } +} + +void updateiMS() { + if (band < BAND_GAP) { + if (iMSset == 0) { + if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { + tft.fillRoundRect(249, 57, 30, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "iMS", 265, 59, BackgroundColor, SecondaryColor); + } + radio.setiMS(1); + } else { + if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { + tft.fillRoundRect(249, 57, 30, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "iMS", 265, 59, BackgroundColor, GreyoutColor); + } + radio.setiMS(0); + } + } +} + +void updateEQ() { + if (band < BAND_GAP) { + if (EQset == 0) { + if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { + tft.fillRoundRect(287, 57, 30, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "EQ", 301, 59, BackgroundColor, SecondaryColor); + } radio.setEQ(1); + } else { + if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { + tft.fillRoundRect(287, 57, 30, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "EQ", 301, 59, BackgroundColor, GreyoutColor); + } radio.setEQ(0); + } + } +} + +inline void DataPrint(String string) { + if (XDRGTKUSB) Serial.print(string); + if (XDRGTKTCP) RemoteClient.print(string); +} + +void toggleiMSEQ() { + if (band < BAND_GAP) { + if (iMSEQ == 0) iMSEQ = 1; + + if (iMSEQ == 4) { + iMSset = 0; + EQset = 0; + updateiMS(); + updateEQ(); + iMSEQ = 0; + } else if (iMSEQ == 3) { + iMSset = 1; + EQset = 0; + updateiMS(); + updateEQ(); + iMSEQ = 4; + } else if (iMSEQ == 2) { + iMSset = 0; + EQset = 1; + updateiMS(); + updateEQ(); + iMSEQ = 3; + } else if (iMSEQ == 1) { + iMSset = 1; + EQset = 1; + updateiMS(); + updateEQ(); + iMSEQ = 2; + } + EEPROM.writeByte(EE_BYTE_IMSSET, iMSset); + EEPROM.writeByte(EE_BYTE_EQSET, EQset); + EEPROM.commit(); + if (XDRGTKUSB || XDRGTKTCP) DataPrint("G" + String(!EQset) + String(!iMSset) + "\n"); + } +} + +void TuneFreq(int temp) { + int newfreq = temp; + + if (band == BAND_FM) { + while (newfreq < (LowEdgeSet * 10)) newfreq *= 10; + if (newfreq > (HighEdgeSet * 10)) { + EdgeBeeper(); + return; + } + if (newfreq == frequency) return; + frequency = newfreq; + radio.SetFreq(frequency); + + } else if (band == BAND_OIRT) { + while (newfreq < (LowEdgeOIRTSet * 10)) newfreq *= 10; + if (newfreq > HighEdgeOIRTSet) { + EdgeBeeper(); + return; + } + if (newfreq == frequency_OIRT) return; + frequency_OIRT = newfreq; + radio.SetFreq(frequency_OIRT); + + } else if (band == BAND_LW) { + while (newfreq < LWLowEdgeSet) newfreq *= 10; + if (newfreq > LWHighEdgeSet) { + EdgeBeeper(); + return; + } + if (newfreq == frequency_LW) return; + frequency_AM = newfreq; + frequency_LW = newfreq; + radio.SetFreqAM(frequency_AM); + } else if (band == BAND_MW) { + while (newfreq < MWLowEdgeSet) newfreq *= 10; + if (newfreq > MWHighEdgeSet) { + EdgeBeeper(); + return; + } + if (newfreq == frequency_MW) return; + frequency_AM = newfreq; + frequency_MW = newfreq; + radio.SetFreqAM(frequency_AM); + } else if (band == BAND_SW) { + while (newfreq < SWLowEdgeSet) newfreq *= 10; + if (newfreq > SWHighEdgeSet) { + EdgeBeeper(); + return; + } + if (newfreq == frequency_SW) return; + frequency_AM = newfreq; + frequency_SW = newfreq; + radio.SetFreqAM(frequency_AM); + } + + aftest = true; + aftimer = millis(); + + radio.clearRDS(); + if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); + if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); +} + +void ShowNum(int val) { + FrequencySprite.setTextDatum(TR_DATUM); + FrequencySprite.fillSprite(BackgroundColor); + FrequencySprite.setTextColor(SecondaryColor, SecondaryColorSmooth, false); + FrequencySprite.drawString(String(val) + " ", 218, -6, freqfont); + FrequencySprite.pushSprite(46, 46); +} + +byte numval[16] = {2, 3, 127, 5, 6, 0, 9, 13, 8, 7, 4, 1, 0, 0, 0, 0}; +int GetNum() { + if(!gpio_chip) return -1; + // Get input port 0 and 1 + Wire.beginTransmission(XL9555_ADDRESS); + Wire.write(0x00); + Wire.endTransmission(); + Wire.requestFrom(XL9555_ADDRESS, 2); + + // According to the schematic of the DP666, this is the table that the buttons are connected to: + // IO0_0 = NUM2 + // IO0_1 = NUM3 + // IO0_2 = BACKSPACE (DX is printed on the case) + // IO0_3 = NUM5 + // IO0_4 = NUM6 + // IO0_5 = NUM0 + // IO0_6 = NUM9 + // IO0_7 = ENTER + // IO1_0 = NUM8 + // IO1_1 = NUM7 + // IO1_2 = NUM4 + // IO1_3 = NUM1 + // Rest is NC + // According to the docs, register 0 contains pins IO0_x where x is equal to the bit from the right (x = 7, is MSB) + + int cnt = 0; + uint16_t temp; + unsigned int num; + if(Wire.available() == 2) { + keypadtimer = millis(); + + temp = Wire.read() & 0xFF; + temp |= (Wire.read() & 0xFF) << 8; + for (int i = 0; i < 16; i++) { + if ((temp & 0x01) == 0) { + num = numval[i]; + cnt++; + } + temp >>= 1; + } + if (cnt == 1) return num; + } + + return -1; +} + +void StoreMemoryPos(uint8_t _pos) { + EEPROM.writeByte(_pos + EE_PRESETS_BAND_START, band); + EEPROM.writeByte(_pos + EE_PRESET_BW_START, BWset); + EEPROM.writeByte(_pos + EE_PRESET_MS_START, StereoToggle); + + if (band == BAND_FM) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency); + else if (band == BAND_OIRT) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_OIRT); + else if (band == BAND_LW) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_LW); + else if (band == BAND_MW) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_MW); + else EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_SW); + + presets[_pos].band = band; + presets[_pos].bw = BWset; + presets[_pos].ms = StereoToggle; + + String stationName = radio.rds.stationName; + char stationNameCharArray[10]; + char picodeArray[7]; + stationName.toCharArray(stationNameCharArray, sizeof(stationNameCharArray)); + memcpy(picodeArray, radio.rds.picode, sizeof(picodeArray)); + + for (int y = 0; y < 9; y++) { + presets[_pos].RDSPS[y] = (y < strlen(stationNameCharArray)) ? stationNameCharArray[y] : '\0'; + EEPROM.writeByte((_pos * 9) + y + EE_PRESETS_RDSPS_START, presets[_pos].RDSPS[y]); + } + + for (int y = 0; y < 5; y++) { + presets[_pos].RDSPI[y] = (y < sizeof(picodeArray)) ? picodeArray[y] : '\0'; + EEPROM.writeByte((_pos * 5) + y + EE_PRESETS_RDSPI_START, presets[_pos].RDSPI[y]); + } + + EEPROM.commit(); + + if (band == BAND_FM) presets[_pos].frequency = frequency; + else if (band == BAND_OIRT) presets[_pos].frequency = frequency_OIRT; + else if (band == BAND_LW) presets[_pos].frequency = frequency_LW; + else if (band == BAND_MW) presets[_pos].frequency = frequency_MW; + else presets[_pos].frequency = frequency_SW; +} + +void startFMDXScan() { + screensavertimer = millis(); + initdxscan = true; + scanholdflag = false; + autologged = false; + + if (menu) endMenu(); + if (afscreen || advancedRDS || rdsstatscreen) { + BuildDisplay(); + freq_in = 0; + } + + memoryposold = memorypos; + if (memorypos > scanstop || memorypos < scanstart) memorypos = scanstart; + scanmodeold = tunemode; + + if (scanmem) { + tunemode = TUNE_MEM; + if (band != presets[memorypos].band) { + band = presets[memorypos].band; + SelectBand(); + } + DoMemoryPosTune(); + } else { + tunemode = TUNE_MAN; + if (band != presets[memorypos].band) { + band = presets[memorypos].band; + SelectBand(); + } + TuneUp(); + ShowFreq(0); + } + if (scanmute) { + radio.setMute(); + tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + SQ = true; + Squelchold = -2; + } + scantimer = millis(); + scandxmode = true; + ShowTuneMode(); + if (XDRGTKUSB || XDRGTKTCP) DataPrint("J1\n"); +} + +void doBandToggle() { + if (tunemode != TUNE_MEM) { + ToggleBand(band); + radio.clearRDS(); + StoreFrequency(); + SelectBand(); + if (XDRGTKUSB || XDRGTKTCP) { + if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); + else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); + else DataPrint("M1\nT" + String(frequency_AM) + "\n"); + } + } else { + scanmodeold = tunemode; + startFMDXScan(); + return; + } + screensavertimer = millis(); +} + +void NumpadProcess(int num) { + if (scandxmode && num == 127) { + ShowFreq(5); + ShowFreq(0); + } else if (tunemode == TUNE_MEM) { + if (num == 127) { + freq_in = 0; + menuoption = ITEM1; + menupage = DXMODE; + menuitem = 0; + submenu = true; + menu = true; + if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); + BuildMenu(); + } else if (num == 13) { + if (freq_in > 0 && freq_in <= EE_PRESETS_CNT) { + byte oldmemorypos = memorypos; + memorypos = freq_in - 1; + if (IsStationEmpty()) { + // Flash red and revert + FrequencySprite.setTextDatum(TR_DATUM); + FrequencySprite.fillSprite(BackgroundColor); + FrequencySprite.setTextColor(SignificantColor, SignificantColorSmooth, false); + FrequencySprite.drawString(String(freq_in) + " ", 218, -6); + FrequencySprite.pushSprite(46, 46); + delay(500); + memorypos = oldmemorypos; + ShowFreq(0); + ShowMemoryPos(); + } else { + DoMemoryPosTune(); + ShowMemoryPos(); + } + } else ShowFreq(0); + freq_in = 0; + } else { + if (freq_in / 100 == 0) { + int temp = freq_in * 10 + num; + if (temp <= EE_PRESETS_CNT) freq_in = temp; + } ShowNum(freq_in); + } + } else { + if (num == 127) { + freq_in = 0; + menuoption = ITEM1; + menupage = DXMODE; + menuitem = 0; + submenu = true; + menu = true; + if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); + BuildMenu(); + } else if (num == 13) { + if (freq_in != 0) { + TuneFreq(freq_in); + if (XDRGTKUSB || XDRGTKTCP) { + if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); + } + if (!memorystore) { + if (!memtune) radio.clearRDS(); + memtune = false; + ShowFreq(0); + store = true; + } + } else ShowFreq(0); + freq_in = 0; + } else { + if (freq_in / 10000 == 0) freq_in = freq_in * 10 + num; + ShowNum(freq_in); + } + } +} + +void setAutoSpeedSPI() { + switch (frequency / 10) { + case 875 ... 877: tft.setSPISpeed(28); break; + case 878 ... 881: tft.setSPISpeed(24); break; + case 882 ... 892: tft.setSPISpeed(42); break; + case 893 ... 899: tft.setSPISpeed(31); break; + case 900 ... 904: tft.setSPISpeed(12); break; + case 905 ... 906: tft.setSPISpeed(16); break; + case 907 ... 910: tft.setSPISpeed(11); break; + case 911 ... 916: tft.setSPISpeed(15); break; + case 917 ... 921: tft.setSPISpeed(24); break; + case 922 ... 928: tft.setSPISpeed(13); break; + case 929: tft.setSPISpeed(11); break; + case 930 ... 932: tft.setSPISpeed(13); break; + case 933 ... 939: tft.setSPISpeed(18); break; + case 940 ... 941: tft.setSPISpeed(12); break; + case 942: tft.setSPISpeed(17); break; + case 943 ... 949: tft.setSPISpeed(15); break; + case 950: tft.setSPISpeed(19); break; + case 951: tft.setSPISpeed(15); break; + case 952 ... 960: tft.setSPISpeed(22); break; + case 961 ... 965: tft.setSPISpeed(15); break; + case 966 ... 973: tft.setSPISpeed(22); break; + case 974 ... 979: tft.setSPISpeed(17); break; + case 980 ... 982: tft.setSPISpeed(20); break; + case 983 ... 987: tft.setSPISpeed(18); break; + case 988 ... 993: tft.setSPISpeed(11); break; + case 994 ... 996: tft.setSPISpeed(18); break; + case 997 ... 1005: tft.setSPISpeed(11); break; + case 1006: tft.setSPISpeed(13); break; + case 1007 ... 1011: tft.setSPISpeed(11); break; + case 1012 ... 1016: tft.setSPISpeed(18); break; + case 1017 ... 1026: tft.setSPISpeed(13); break; + case 1027 ... 1035: tft.setSPISpeed(23); break; + case 1036 ... 1038: tft.setSPISpeed(15); break; + case 1039 ... 1042: tft.setSPISpeed(12); break; + case 1043 ... 1047: tft.setSPISpeed(23); break; + case 1048 ... 1050: tft.setSPISpeed(28); break; + case 1051 ... 1062: tft.setSPISpeed(15); break; + case 1063 ... 1068: tft.setSPISpeed(18); break; + case 1069 ... 1074: tft.setSPISpeed(14); break; + case 1075: tft.setSPISpeed(17); break; + case 1076 ... 1080: tft.setSPISpeed(15); break; + default: tft.setSPISpeed(35); break; + } +} + +void endMenu() { + if(rds_settings_changed) { + radio.clearRDS(); + RDSstatus = false; + } + rds_settings_changed = menu = false; + menuopen = false; + LowLevelInit = true; + submenu = false; + menuoption = ITEM1; + menupage = INDEX; + menuitem = 0; + saveData(); + if (af == 2) radio.rds.afreg = true; else radio.rds.afreg = false; + Serial.end(); + if (wifi) remoteip = IPAddress(WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], subnetclient); + if (USBmode) Serial.updateBaudRate(19200); else Serial.updateBaudRate(115200); + + leave = true; + if (language == LANGUAGE_CHS) PSSprite.setTextFont(3); else PSSprite.setTextFont(2); + PSSprite.setTextDatum(TL_DATUM); + BuildDisplay(); + SelectBand(); +} + +void cancelDXScan() { + tunemode = scanmodeold; + memorypos = memoryposold; + scandxmode = false; + if (scanmute) { + radio.setUnMute(); + tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + + if (!flashing) { + tft.fillRoundRect(2, 80, 40, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SecondaryColor); + } + + SQ = false; + Squelchold = -2; + } + + ShowTuneMode(); + ShowMemoryPos(); + if (XDRGTKUSB || XDRGTKTCP) DataPrint("J0\n"); +} + +void MuteScreen(bool setting) { + if (!setting && screenmute) { + screenmute = false; + setupmode = true; + leave = true; + tft.writecommand(0x11); + analogWrite(CONTRASTPIN, map(ContrastSet, 0, 100, 0, 255)); + if (band < BAND_GAP) { + if (afscreen) { + BuildAFScreen(); + freq_in = 0; + } else if (advancedRDS) { + BuildAdvancedRDS(); + freq_in = 0; + } else if (rdsstatscreen) { + BuildRDSStatScreen(); + freq_in = 0; + } else { + BuildDisplay(); + freq_in = 0; + SelectBand(); + } + } else { + BuildDisplay(); + freq_in = 0; + SelectBand(); + } setupmode = false; + } else if (setting && !screenmute) { + screenmute = true; + analogWrite(CONTRASTPIN, 0); + tft.writecommand(0x10); + } +} +#pragma endregion + +void ShowAudioLevel(); +void doSquelch(); +void handleWiFi() { + if (wifi && !menu) { + webserver.handleClient(); + + if (millis() >= udplogtimer + UDP_LOG_INTERVAL_MS) { + sendUDPlog(); + udplogtimer = millis(); + } + + if (millis() >= NTPtimer + NTP_UPDATE_INTERVAL_MS) { + NTPupdate(); + NTPtimer = millis(); + } + } +} + +void handleTouch() { + if (hardwaremodel == PORTABLE_TOUCH_ILI9341 && touch_detect) { + if (tft.getTouchRawZ() > TOUCH_RAW_Z_THRESHOLD) { + uint16_t x, y; + tft.getTouch(&x, &y); + if (x > 0 || y > 0) { + if (!firstTouchHandled) { + doTouchEvent(x, y); + firstTouchHandled = true; + lastTouchTime = millis(); + } else if (touchrepeat && millis() - lastTouchTime >= DELAY_TOUCH_REPEAT_MS) doTouchEvent(x, y); + } + } else { + firstTouchHandled = false; + touch_detect = false; + } + } +} + +void handleTimers() { + // tottimer is like the time of the last interaction + if (tot != 0 && millis() >= tottimer + (tot * TOT_MULTIPLIER_MS)) deepSleep(); + + if (freq_in != 0 && millis() >= keypadtimer + DELAY_KEYPAD_TIMEOUT_MS) { + freq_in = 0; + ShowFreq(0); + if (tunemode == TUNE_MEM) ShowMemoryPos(); + } +} + +void loop() { + if(i2c_pc_control) { + total_pc_control(); + if(i2c_pc_control) return; + } + + handleWiFi(); + handleTouch(); + Communication(); + handleTimers(); + + if (scandxmode) { + unsigned long waitTime = (scanhold == 0) ? SCAN_HOLD_DEFAULT_MS : (scanhold * 1000); + if (!scanholdflag) scanholdflag = isSignalQualityGood(USN, WAM, OStatus); + bool bypassMillisCheck = scanholdonsignal && !scanholdflag; + bool shouldScan = bypassMillisCheck || (!bypassMillisCheck && (millis() >= scantimer + waitTime)); + + if (shouldScan) { + if (scanmute && scanholdonsignal) { + radio.setMute(); + if (!screenmute) tft.drawBitmap(SPEAKER_ICON_X, SPEAKER_ICON_Y, Speaker, SPEAKER_ICON_WIDTH, SPEAKER_ICON_HEIGHT, PrimaryColor); + SQ = true; + } + scanholdflag = false; + if (scanmem) { + memorypos++; + if (memorypos > scanstop) memorypos = scanstart; + while (IsStationEmpty() || (presets[memorypos].band != BAND_FM && presets[memorypos].band != BAND_OIRT)) { + memorypos++; + if (memorypos > scanstop) { + memorypos = scanstart; + break; + } + } + doLog(); + DoMemoryPosTune(); + radio.clearRDS(); + autologged = false; + ShowMemoryPos(); + } else { + doLog(); + TuneUp(); + autologged = false; + ShowFreq(0); + if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); + } + scantimer = millis(); + initdxscan = false; + } else { + if (scanmute && scanholdonsignal) { + radio.setUnMute(); + SQ = false; + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + } + } + + if (millis() >= flashingtimer + 500) { + flashing = !flashing; + if (flashing) { + tft.fillRoundRect(2, 80, 40, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SecondaryColor); + } else { + tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); + } + flashingtimer = millis(); + } + + if (!scanholdflag) delay(75); + radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + + if (!initdxscan) { + switch (scancancel) { + case CORRECTPI: + if (RDSstatus && radio.rds.correctPI != 0) cancelDXScan(); + break; + case SIGNAL: + if (isSignalQualityGood(USN, WAM, OStatus) && (Squelch < SStatus || Squelch == SQUELCH_MAX_VALUE)) cancelDXScan(); + break; + } + } + } + + if (millis() >= tuningtimer + 200) rdsflagreset = false; + + if (millis() >= tuningtimer + 2000) { + if (store) { + StoreFrequency(); + store = false; + } + } + + if (!BWtune && !menu && !afscreen && !rdsstatscreen && !scandxmode) { + if (af != 0 && dropout && millis() >= aftimer + 1000) { + aftimer = millis(); + if (radio.af_counter == 0) { + if (findMemoryAF && radio.rds.correctPI != 0 && tunemode == TUNE_MEM && (USN > 250 || WAM > 250)) { + radio.setMute(); + tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + SQ = true; + if (!screenmute) { + if (advancedRDS) { + tft.drawRoundRect(10, 30, 300, 170, 2, ActiveColor); + tft.fillRoundRect(12, 32, 296, 166, 2, BackgroundColor); + tftPrint(ACENTER, textUI(31), 160, 100, ActiveColor, ActiveColorSmooth, 28); + } else ShowFreq(1); + } + + bool foundmemaf = false; + for (int x = 8750; x <= 10800; x += 10) { + if (rotary != 0 || digitalRead(BANDBUTTON) == LOW || digitalRead(MODEBUTTON) == LOW || digitalRead(BWBUTTON) == LOW || digitalRead(ROTARY_BUTTON) == LOW) break; + radio.SetFreq(x); + unsigned long millisold = millis(); + while (millis() - millisold < 187) { + if (!screenmute && !advancedRDS) ShowAudioLevel(); + } + if (radio.rds.correctPI == radio.getBlockA()) { + frequency = x; + foundmemaf = true; + break; + } + } + + if (!foundmemaf) { + frequency = freqold; + radio.SetFreq(frequency); + } + + if (!screenmute) { + if (advancedRDS) { + leave = true; + BuildAdvancedRDS(); + freq_in = 0; + } else ShowFreq(0); + } + + radio.setUnMute(); + SQ = false; + tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + } + findMemoryAF = false; + } else frequency = radio.TestAF(); + if (freqold != frequency) { + ShowFreq(0); + dropout = true; + if (radio.afmethodB) { + afmethodBold = true; + radio.clearRDS(); + } + } + if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); + if (screenmute) { + freqold = frequency; + dropout = false; + } + store = true; + } + + if (band == BAND_FM && af != 0 && radio.rds.correctPI != 0) { + if ((aftest && millis() >= aftimer + 3000) || ((USN > 250 || WAM > 250) && millis() >= aftimer + 1000)) { + aftimer = millis(); + aftest = false; + frequency = radio.TestAF(); + if (freqold != frequency) { + ShowFreq(0); + dropout = true; + if (radio.afmethodB) { + afmethodBold = true; + radio.clearRDS(); + } + if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); + if (screenmute) { + freqold = frequency; + dropout = false; + } + store = true; + } + } + + if (band == BAND_FM && millis() >= aftimer + 10000) { + aftimer = millis(); + if (USN > 150 || WAM > 150) { + frequency = radio.TestAF(); + if (freqold != frequency) { + ShowFreq(0); + dropout = true; + if (radio.afmethodB) { + afmethodBold = true; + radio.clearRDS(); + } + if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); + store = true; + if (screenmute) { + freqold = frequency; + dropout = false; + } + } + } + } + } + } + + if(seek) Seek(direction); + + if ((SStatus / 10 > LowLevelSet) && !LowLevelInit && !BWtune && !menu && band < BAND_GAP) { + if (!screenmute && !advancedRDS && !rdsstatscreen && !afscreen) { + if (showaudio) { + tftPrint16(ALEFT, "10", 24, 144, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "30", 54, 144, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "50", 84, 144, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "70", 114, 144, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "100", 160, 144, ActiveColor, ActiveColorSmooth); + tftPrint16(ACENTER, "A", 7, 128, ActiveColor, ActiveColorSmooth); + for (byte segments = 0; segments < 93; segments++) { + if (segments > 54) { + if (((segments - 53) % 10) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, BarSignificantColor); + } else { + if (((segments + 1) % 6) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, BarInsignificantColor); + } + } + } + if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, ActiveColor, ActiveColorSmooth); + else { + tftPrint16(ALEFT, "PI", 212, 184, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "ID", 212, 201, ActiveColor, ActiveColorSmooth); + } + tftPrint16(ALEFT, "PS", 3, 193, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "RT", 3, 221, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "PTY", 3, 163, ActiveColor, ActiveColorSmooth); + if (!showaudio) tft.drawLine(16, 143, 189, 143, GreyoutColor); else tft.drawLine(16, 143, 189, 143, ActiveColor); + } + LowLevelInit = true; + } + + if ((SStatus / 10 <= LowLevelSet) && band < BAND_GAP) { + if (LowLevelInit && !BWtune && !menu) { + if (!screenmute && !rdsstatscreen && !afscreen && !advancedRDS) { + if(showaudio) { + tftPrint16(ALEFT, "10", 24, 144, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "30", 54, 144, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "50", 84, 144, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "70", 114, 144, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "100", 160, 144, GreyoutColor, BackgroundColor); + tftPrint16(ACENTER, "A", 7, 128, GreyoutColor, BackgroundColor); + tft.fillRect(16, 133, 174, 6, GreyoutColor); + for (byte segments = 0; segments < 93; segments++) { + if (segments > 54) { + if (((segments - 53) % 10) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, GreyoutColor); + } else { + if (((segments + 1) % 6) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, GreyoutColor); + } + } + } + if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, GreyoutColor, BackgroundColor); + else { + tftPrint16(ALEFT, "PI", 212, 184, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "ID", 212, 201, GreyoutColor, BackgroundColor); + } + tftPrint16(ALEFT, "PS", 3, 193, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "RT", 3, 221, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "PTY", 3, 163, GreyoutColor, BackgroundColor); + tft.drawLine(16, 143, 189, 143, GreyoutColor); + tft.drawBitmap(68, 5, RDSLogo, 35, 22, GreyoutColor); + } + LowLevelInit = false; + } + + if (!BWtune && !menu && (screenmute || radio.rds.correctPI != 0)) readRds(); + if (millis() >= lowsignaltimer + 300) { + lowsignaltimer = millis(); + if (af || (!screenmute || (screenmute && (XDRGTKTCP || XDRGTKUSB)))) { + if (band < BAND_GAP) radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + else radio.getStatusAM(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + } + if (!BWtune && !menu) { + doSquelch(); + GetData(); + } + } + + } else { + if (af || (!screenmute || (screenmute && (XDRGTKTCP || XDRGTKUSB)))) { + if (band < BAND_GAP) radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + else radio.getStatusAM(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + } + if (!BWtune && !menu) { + doSquelch(); + if (millis() >= tuningtimer + 200) readRds(); + GetData(); + if (!screenmute && !rdsstatscreen && !afscreen && !advancedRDS) ShowAudioLevel(); + } + } + + if (rotary == -1) { + tottimer = millis(); + if (screensavertriggered) { + if (!touchrotating) { + rotary = 0; + WakeToSleep(REVERSE); + } else { + if (BWtune) doBWtuneUp(); else KeyUp(); + } + } else { + if (BWtune) doBWtuneUp(); else KeyUp(); + if (rotaryaccelerate && rotarycounter > 2 && !BWtune && !menu) { + for (int i = 0; i < rotarycounteraccelerator; i++) KeyUp(); + rotarycounter = 0; + } + if (screensaverset > 0 && !BWtune && !menu && !screensavertriggered) screensavertimer = millis(); + } + } + + if (rotary == 1) { + tottimer = millis(); + if (screensavertriggered) { + if (!touchrotating) { + rotary = 0; + WakeToSleep(REVERSE); + } else { + if (BWtune) doBWtuneDown(); else KeyDown(); + } + } else { + if (BWtune) doBWtuneDown(); else KeyDown(); + if (rotaryaccelerate && rotarycounter > 2 && !BWtune && !menu) { + for (int i = 0; i < rotarycounteraccelerator; i++) KeyDown(); + rotarycounter = 0; + } + if (screensaverset > 0 && !BWtune && !menu && !screensavertriggered) screensavertimer = millis(); + } + } + + if (digitalRead(BANDBUTTON) == LOW) { + tottimer = millis(); + if (screensavertriggered) { + WakeToSleep(REVERSE); + while (digitalRead(BANDBUTTON) == LOW); + } else BANDBUTTONPress(); + } + + if (digitalRead(ROTARY_BUTTON) == LOW) { + tottimer = millis(); + if (screensavertriggered) { + WakeToSleep(REVERSE); + while (digitalRead(ROTARY_BUTTON) == LOW); + } else if (!afscreen && !rdsstatscreen) ButtonPress(); + } + + if (digitalRead(MODEBUTTON) == LOW) { + tottimer = millis(); + if (screensavertriggered) { + WakeToSleep(REVERSE); + while (digitalRead(MODEBUTTON) == LOW); + } else if(!screenmute) ModeButtonPress(); + } + + if (digitalRead(BWBUTTON) == LOW && !BWtune) { + tottimer = millis(); + if (screensavertriggered) { + WakeToSleep(REVERSE); + while (digitalRead(BWBUTTON) == LOW); + } else if(!screenmute) BWButtonPress(); + } + + if (digitalRead(EXT_IRQ) == LOW) { + if (screensavertriggered) WakeToSleep(REVERSE); + int num = GetNum(); + if (!screenmute && !BWtune && !menu && !advancedRDS && !rdsstatscreen && !afscreen && num != -1) NumpadProcess(num); + } + + if (screensaverset > 0 && !screensavertriggered && !BWtune && !menu && millis() >= screensavertimer + 1000 * screensaverOptions[screensaverset]) WakeToSleep(true); +} + +void DivdeSWMIBand() { + if (frequency_AM >= FREQ_SW_160M_START && frequency_AM <= FREQ_SW_160M_END) { + SWMIBandPos = SW_MI_BAND_160M; + frequency_MIBand_160M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_120M_START && frequency_AM <= FREQ_SW_120M_END) { + SWMIBandPos = SW_MI_BAND_120M; + frequency_MIBand_120M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_90M_START && frequency_AM <= FREQ_SW_90M_END) { + SWMIBandPos = SW_MI_BAND_90M; + frequency_MIBand_90M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_75M_START && frequency_AM <= FREQ_SW_75M_END) { + SWMIBandPos = SW_MI_BAND_75M; + frequency_MIBand_75M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_60M_START && frequency_AM <= FREQ_SW_60M_END) { + SWMIBandPos = SW_MI_BAND_60M; + frequency_MIBand_60M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_49M_START && frequency_AM <= FREQ_SW_49M_END) { + SWMIBandPos = SW_MI_BAND_49M; + frequency_MIBand_49M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_41M_START && frequency_AM <= FREQ_SW_41M_END) { + SWMIBandPos = SW_MI_BAND_41M; + frequency_MIBand_41M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_31M_START && frequency_AM <= FREQ_SW_31M_END) { + SWMIBandPos = SW_MI_BAND_31M; + frequency_MIBand_31M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_25M_START && frequency_AM <= FREQ_SW_25M_END) { + SWMIBandPos = SW_MI_BAND_25M; + frequency_MIBand_25M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_22M_START && frequency_AM <= FREQ_SW_22M_END) { + SWMIBandPos = SW_MI_BAND_22M; + frequency_MIBand_22M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_19M_START && frequency_AM <= FREQ_SW_19M_END) { + SWMIBandPos = SW_MI_BAND_19M; + frequency_MIBand_19M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_16M_START && frequency_AM <= FREQ_SW_16M_END) { + SWMIBandPos = SW_MI_BAND_16M; + frequency_MIBand_16M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_15M_START && frequency_AM <= FREQ_SW_15M_END) { + SWMIBandPos = SW_MI_BAND_15M; + frequency_MIBand_15M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_13M_START && frequency_AM <= FREQ_SW_13M_END) { + SWMIBandPos = SW_MI_BAND_13M; + frequency_MIBand_13M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else if (frequency_AM >= FREQ_SW_11M_START && frequency_AM <= FREQ_SW_11M_END) { + SWMIBandPos = SW_MI_BAND_11M; + frequency_MIBand_11M = frequency_AM; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + } else { + if (SWMIBandPos > SW_MI_BAND_GAP) { + SWMIBandPosold = SWMIBandPos; + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + } SWMIBandPos = SW_MI_BAND_GAP; + } +} + +void ToggleSWMIBand(bool frequencyup) { + switch (SWMIBandPosold) { + case SW_MI_BAND_GAP: + if (frequencyup) { + SWMIBandPos = SW_MI_BAND_160M; + SWMIBandPosold = SWMIBandPos; + frequency_AM = FREQ_SW_160M_START; + } else { + SWMIBandPos = SW_MI_BAND_11M; + SWMIBandPosold = SWMIBandPos; + frequency_AM = FREQ_SW_11M_END; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_11M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_160M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_160M == 0 ? FREQ_SW_160M_START : frequency_MIBand_160M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_13M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_13M == 0 ? FREQ_SW_13M_END : frequency_MIBand_13M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_13M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_11M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_11M == 0 ? FREQ_SW_11M_START : frequency_MIBand_11M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_15M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_15M == 0 ? FREQ_SW_15M_END : frequency_MIBand_15M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_15M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_13M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_13M == 0 ? FREQ_SW_13M_START : frequency_MIBand_13M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_16M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_16M == 0 ? FREQ_SW_16M_END : frequency_MIBand_16M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_16M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_15M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_15M == 0 ? FREQ_SW_15M_START : frequency_MIBand_15M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_19M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_19M == 0 ? FREQ_SW_19M_END : frequency_MIBand_19M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_19M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_16M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_16M == 0 ? FREQ_SW_16M_START : frequency_MIBand_16M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_22M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_22M == 0 ? FREQ_SW_22M_END : frequency_MIBand_22M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_22M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_19M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_19M == 0 ? FREQ_SW_19M_START : frequency_MIBand_19M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_25M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_25M == 0 ? FREQ_SW_25M_END : frequency_MIBand_25M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_25M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_22M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_22M == 0 ? FREQ_SW_22M_START : frequency_MIBand_22M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_31M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_31M == 0 ? FREQ_SW_31M_END : frequency_MIBand_31M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_31M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_25M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_25M == 0 ? FREQ_SW_25M_START : frequency_MIBand_25M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_41M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_41M == 0 ? FREQ_SW_41M_END : frequency_MIBand_41M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_41M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_31M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_31M == 0 ? FREQ_SW_31M_START : frequency_MIBand_31M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_49M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_49M == 0 ? FREQ_SW_49M_END : frequency_MIBand_49M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_49M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_41M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_41M == 0 ? FREQ_SW_41M_START : frequency_MIBand_41M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_60M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_60M == 0 ? FREQ_SW_60M_END : frequency_MIBand_60M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_60M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_49M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_49M == 0 ? FREQ_SW_49M_START : frequency_MIBand_49M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_75M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_75M == 0 ? FREQ_SW_75M_END : frequency_MIBand_75M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_75M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_60M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_60M == 0 ? FREQ_SW_60M_START : frequency_MIBand_60M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_90M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_90M == 0 ? FREQ_SW_90M_END : frequency_MIBand_90M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_90M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_75M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_75M == 0 ? FREQ_SW_75M_START : frequency_MIBand_75M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_120M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_120M == 0 ? FREQ_SW_120M_END : frequency_MIBand_120M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_120M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_90M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_90M == 0 ? FREQ_SW_90M_START : frequency_MIBand_90M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_160M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_160M == 0 ? FREQ_SW_160M_END : frequency_MIBand_160M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + case SW_MI_BAND_160M: + if (frequencyup) { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_120M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_120M == 0 ? FREQ_SW_120M_START : frequency_MIBand_120M; + } else { + SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; + SWMIBandPos = SW_MI_BAND_11M; + SWMIBandPosold = SWMIBandPos; + SWMIBandstring = (String) "" + SWMIBandPos + " m"; + frequency_AM = frequency_MIBand_11M == 0 ? FREQ_SW_49M_END : frequency_MIBand_11M; + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + break; + } +} + +void SelectBand() { + if (afscreen || advancedRDS || rdsstatscreen) { + BuildDisplay(); + freq_in = 0; + } + + if (band > BAND_GAP) { + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + if (tunemode == TUNE_MI_BAND && band != BAND_SW) tunemode = TUNE_MAN; + BWreset = true; + BWset = BWsetAM; + switch (band) { + case BAND_LW: freqold = frequency_LW; frequency_AM = frequency_LW; break; + case BAND_MW: freqold = frequency_MW; frequency_AM = frequency_MW; break; + case BAND_SW: freqold = frequency_SW; frequency_AM = frequency_SW; break; + } + LimitAMFrequency(); + if (!externaltune && tunemode != TUNE_MEM) CheckBandForbiddenAM(); + radio.SetFreqAM(frequency_AM); + radio.setAMAttenuation(amgain); + radio.setAMCoChannel(amcodect, amcodectcount); + doBW(); + if (!screenmute) { + if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, GreyoutColor, BackgroundColor); + else { + tftPrint16(ALEFT, "PI", 212, 184, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "ID", 212, 201, GreyoutColor, BackgroundColor); + } + + tftPrint16(ALEFT, "PS", 3, 193, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "RT", 3, 221, GreyoutColor, BackgroundColor); + tftPrint16(ALEFT, "PTY", 3, 163, GreyoutColor, BackgroundColor); + tft.drawBitmap(68, 5, RDSLogo, 35, 22, GreyoutColor); + tft.fillRoundRect(249, 57, 30, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "iMS", 265, 59, BackgroundColor, GreyoutColor); + tft.fillRoundRect(287, 57, 30, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "EQ", 301, 59, BackgroundColor, GreyoutColor); + tftReplace(ALEFT, "MHz", "kHz", 258, 76, ActiveColor, ActiveColorSmooth, BackgroundColor, 28); + } + } else { + if (tunemode == TUNE_MI_BAND) tunemode = TUNE_MAN; + + if (!leave) { + if (band == BAND_FM) radio.SetFreq(frequency); + if (band == BAND_OIRT) radio.SetFreq(frequency_OIRT); + } + + BWreset = true; + BWset = BWsetFM; + freqold = frequency_AM; + if (!externaltune && tunemode != TUNE_MEM) CheckBandForbiddenFM(); + doBW(); + if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, ActiveColor, ActiveColorSmooth); + else { + tftPrint16(ALEFT, "PI", 212, 184, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "ID", 212, 201, ActiveColor, ActiveColorSmooth); + } + tftPrint16(ALEFT, "PS", 3, 193, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "RT", 3, 221, ActiveColor, ActiveColorSmooth); + tftPrint16(ALEFT, "PTY", 3, 163, ActiveColor, ActiveColorSmooth); + + tftReplace(ALEFT, "kHz", "MHz", 258, 76, ActiveColor, ActiveColorSmooth, BackgroundColor, 28); + } + + if (!leave) radio.clearRDS(); + ShowFreq(0); + + if (!screenmute) { + tft.fillRect(113, 38, 124, 4, BackgroundColor); + ShowErrors(); + showPTY(); + showRadioText(); + showPI(); + updateiMS(); + updateEQ(); + ShowTuneMode(); + ShowStepSize(); + + tftPrint(ALEFT, textUI(99), 70, 32, BackgroundColor, BackgroundColor, 16); + tftPrint(ALEFT, textUI(100), 70, 32, BackgroundColor, BackgroundColor, 16); + tftPrint(ALEFT, textUI(101), 70, 32, BackgroundColor, BackgroundColor, 16); + tftPrint(ALEFT, textUI(102), 70, 32, BackgroundColor, BackgroundColor, 16); + tftPrint(ALEFT, textUI(103), 70, 32, BackgroundColor, BackgroundColor, 16); + + switch (band) { + case BAND_LW: tftPrint(ALEFT, textUI(99), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; + case BAND_MW: tftPrint(ALEFT, textUI(100), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; + case BAND_SW: tftPrint(ALEFT, textUI(101), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; + case BAND_FM: tftPrint(ALEFT, textUI(102), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; + case BAND_OIRT: tftPrint(ALEFT, textUI(103), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; + } + } + leave = false; +} + +void ModeButtonPress() { + if (seek) radio.setUnMute(); + seek = false; + if (scandxmode) { + ShowFreq(5); + ShowFreq(0); + } else { + if (!usesquelch) radio.setUnMute(); + if (advancedRDS) { + BuildDisplay(); + freq_in = 0; + SelectBand(); + screensavertimer = millis(); + } else if (afscreen) { + if (afpagenr == 1) afpagenr = 2; else if (afpagenr == 2 && afpage) afpagenr = 3; else afpagenr = 1; + BuildAFScreen(); + freq_in = 0; + } else if (rdsstatscreen) { + BuildAFScreen(); + freq_in = 0; + } else { + if (!BWtune && !menu) { + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + memorystore = false; + unsigned long counterold = millis(); + unsigned long counter = millis(); + while (digitalRead(MODEBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); + + if (counter - counterold <= 1000) { + doTuneMode(); + } else { + if (!BWtune && !menu) { + menuoption = ITEM1; + menupage = INDEX; + menuitem = 0; + if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); + BuildMenu(); + freq_in = 0; + menu = true; + } + } + } else { + if (menuopen && !submenu) { + ButtonPress(); + } else if (!submenu) { + OStatusold = 1000; + Stereostatusold = false; + SStatusold = 2000; + BWOld = 0; + if (frequency % 10 != 0) { + if (fmdefaultstepsize == 1) Round100K(frequency); else Round50K(frequency); + EEPROM.writeUInt(EE_UINT16_FREQUENCY_FM, frequency); + } + CheckBandForbiddenFM(); + CheckBandForbiddenAM(); + if (!usesquelch) radio.setUnMute(); + MWLowEdgeSet = mwstepsize == false ? FREQ_MW_LOW_EDGE_MIN_9K : FREQ_MW_LOW_EDGE_MIN_10K; + MWHighEdgeSet = mwstepsize == false ? FREQ_MW_HIGH_EDGE_MAX_9K : FREQ_MW_HIGH_EDGE_MAX_10K; + doBandSelectionFM(); + doBandSelectionAM(); + screensavertimer = millis(); + endMenu(); + } else { + if (submenu) { + if (menuopen) { + if (menupage == CONNECTIVITY && menuoption == ITEM2 && wifi) { + tryWiFi(); + delay(1750); + } + if (menupage == DISPLAYSETTINGS && menuoption == ITEM5) doTheme(); + menuopen = false; + } + submenu = false; + menuoption = ITEM1; + menupage = INDEX; + menuitem = 0; + if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); + BuildMenu(); + freq_in = 0; + } + } + } + } + } + while (digitalRead(MODEBUTTON) == LOW) delay(50); + delay(50); +} + +void RoundStep() { + if (band == BAND_FM) { + unsigned int freq = frequency; + switch (fmdefaultstepsize) { + case 0: Round50K(freq); break; + case 1: Round100K(freq); break; + case 2: Round200K(freq); break; + } + radio.SetFreq(frequency); + } else if (band == BAND_OIRT) { + Round30K(frequency_OIRT); + radio.SetFreq(frequency_OIRT); + } else { + if (band == BAND_LW) { + unsigned int freq = frequency_AM / (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); + frequency_AM = freq * (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); + frequency_LW = frequency_AM; + radio.SetFreqAM(frequency_AM); + } else if (band == BAND_MW) { + unsigned int freq = frequency_AM / (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); + frequency_AM = freq * (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); + frequency_MW = frequency_AM; + radio.SetFreqAM(frequency_AM); + } else if (band == BAND_SW) { + Round5K(frequency_AM); + frequency_SW = frequency_AM; + radio.SetFreqAM(frequency_AM); + } + } StoreFrequency(); + + while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); +} + +void ButtonPress() { + if (seek) radio.setUnMute(); + seek = false; + if (scandxmode) { + ShowFreq(5); + ShowFreq(0); + } else { + if (!usesquelch) radio.setUnMute(); + if (advancedRDS) { + BuildDisplay(); + freq_in = 0; + SelectBand(); + } + if (!BWtune && !menu) { + if (tunemode == TUNE_MEM) { + if (!memorystore) { + memorystore = true; + if (!IsStationEmpty()) memoryposstatus = MEM_EXIST; + else memoryposstatus = MEM_NORMAL; + ShowMemoryPos(); + + ShowTuneMode(); + } else { + memorystore = false; + StoreMemoryPos(memorypos); + + ShowTuneMode(); + if (memoryposstatus == MEM_DARK || memoryposstatus == MEM_EXIST) { + memoryposstatus = MEM_NORMAL; + ShowMemoryPos(); + } + } + } else { + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + unsigned long counterold = millis(); + unsigned long counter = millis(); + while (digitalRead(ROTARY_BUTTON) == LOW && counter - counterold <= 1000) counter = millis(); + + if (counter - counterold < 1000) { + if (tunemode == TUNE_MAN) { + stepsize++; + if((band == BAND_SW || band < BAND_GAP) && stepsize > 4) stepsize = 0; + else if(stepsize > 3) stepsize = 0; + + if (!screenmute) ShowStepSize(); + + EEPROM.writeByte(EE_BYTE_STEPSIZE, stepsize); + EEPROM.commit(); + if (stepsize == 0) { + RoundStep(); + ShowFreq(0); + } + } + } else { + if (band < BAND_GAP) { + switch (addRowToCSV()) { + case 0: ShowFreq(2); break; + case 1: ShowFreq(3); break; + case 2: ShowFreq(4); break; + } + delay(DELAY_UI_UPDATE_MS); + EdgeBeeper(); + while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); + ShowFreq(0); + } else { + if (band == BAND_SW && tunemode != TUNE_MEM) { + nowToggleSWMIBand = !nowToggleSWMIBand; + tunemode = TUNE_MAN; + EEPROM.writeByte(EE_BYTE_BANDAUTOSW, nowToggleSWMIBand); + EEPROM.commit(); + if (!screenmute) { + tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, BackgroundColor); + tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, BackgroundColor); + } + doTuneMode(); + ShowTuneMode(); + } + } + } + } + screensavertimer = millis(); + } else { + if (menu) DoMenu(); + if (BWtune) { + if (BWsettemp == 18 || BWsettemp == 19) { + if (BWsettemp == 18) iMSset = !iMSset; + if (BWsettemp == 19) EQset = !EQset; + if(!iMSset && !EQset) iMSEQ = 0; + else if(iMSset && EQset) iMSEQ = 2; + else if(!iMSset && EQset) iMSEQ = 3; + else iMSEQ = 4; + EEPROM.writeByte(EE_BYTE_IMSSET, iMSset); + EEPROM.writeByte(EE_BYTE_EQSET, EQset); + EEPROM.commit(); + updateiMS(); + updateEQ(); + if (XDRGTKUSB || XDRGTKTCP) DataPrint("G" + String(!EQset) + String(!iMSset) + "\n"); + showBWSelector(); + if (band < BAND_GAP) drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsFM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); + else drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsAM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); + } else if (BWsettemp == 20) { + BuildDisplay(); + freq_in = 0; + SelectBand(); + } else { + doBW(); + showBWSelector(); + if (band < BAND_GAP) drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsFM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); + else drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsAM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); + } + } + } + } + while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); +} + +void KeyUp() { + rotary = 0; + if (scandxmode) { + ShowFreq(5); + ShowFreq(0); + } else { + if (!afscreen && !rdsstatscreen) { + if (!BWtune && !menu) { + switch (tunemode) { + case TUNE_MAN: + TuneUp(); + break; + case TUNE_AUTO: + direction = true; + seek = true; + seekinit = true; + Seek(direction); + break; + case TUNE_MEM: + memorypos++; + if (memorypos > EE_PRESETS_CNT - 1) memorypos = 0; + if (!memorystore) { + while (IsStationEmpty()) { + memorypos++; + if (memorypos > EE_PRESETS_CNT - 1) { + memorypos = 0; + break; + } + } + } + if (!memorystore) DoMemoryPosTune(); + else { + if (!IsStationEmpty()) memoryposstatus = MEM_EXIST; else memoryposstatus = MEM_DARK; + } + ShowMemoryPos(); + EEPROM.writeByte(EE_BYTE_MEMORYPOS, memorypos); + EEPROM.commit(); + break; + case TUNE_MI_BAND: + if (showSWMIBand) { + if (displayflip) ToggleSWMIBand(true); + else ToggleSWMIBand(REVERSE); + } + break; + } + if (XDRGTKUSB || XDRGTKTCP) { + if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); + } + if (!memorystore) { + if (!memtune) radio.clearRDS(); + memtune = false; + ShowFreq(0); + store = true; + } + } else MenuUpDown(true); + } + } +} + +void KeyDown() { + rotary = 0; + if (scandxmode) { + ShowFreq(5); + ShowFreq(0); + } else { + if (!afscreen && !rdsstatscreen) { + if (!BWtune && !menu) { + switch (tunemode) { + case TUNE_MAN: + TuneDown(); + break; + case TUNE_AUTO: + direction = false; + seek = true; + seekinit = true; + Seek(direction); + break; + case TUNE_MEM: + memorypos--; + if (memorypos > EE_PRESETS_CNT - 1) memorypos = EE_PRESETS_CNT - 1; + if (!memorystore) { + while (IsStationEmpty()) { + memorypos--; + if (memorypos > EE_PRESETS_CNT - 1) { + memorypos = EE_PRESETS_CNT - 1; + break; + } + } + } + if (!memorystore) DoMemoryPosTune(); + else { + if (!IsStationEmpty()) memoryposstatus = MEM_EXIST; else memoryposstatus = MEM_DARK; + } + ShowMemoryPos(); + EEPROM.writeByte(EE_BYTE_MEMORYPOS, memorypos); + EEPROM.commit(); + break; + case TUNE_MI_BAND: + if (showSWMIBand) { + if (displayflip) ToggleSWMIBand(REVERSE); + else ToggleSWMIBand(true); + } + break; + } + if (XDRGTKUSB || XDRGTKTCP) { + if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); + } + if (!memorystore) { + if (!memtune) radio.clearRDS(); + memtune = false; + ShowFreq(0); + store = true; + } + } else MenuUpDown(false); + } + } +} + +void ShowMemoryPos() { + if (tunemode == TUNE_MEM) { + int memposcolor = 0; + int memposcolorsmooth = 0; + + if (!memorystore) { + if (IsStationEmpty()) memoryposstatus = MEM_DARK; else memoryposstatus = MEM_NORMAL; + } + + switch (memoryposstatus) { + case MEM_DARK: + memposcolor = InsignificantColor; + memposcolorsmooth = InsignificantColorSmooth; + break; + + case MEM_NORMAL: + memposcolor = PrimaryColor; + memposcolorsmooth = PrimaryColorSmooth; + break; + + case MEM_EXIST: + memposcolor = SignificantColor; + memposcolorsmooth = SignificantColorSmooth; + break; + } + if (advancedRDS) tftReplace(ALEFT, String(memoryposold + 1), String(memorypos + 1), 215, 36, SecondaryColor, SecondaryColorSmooth, BackgroundColor, 16); + else tftReplace(ALEFT, String(memoryposold + 1), String(memorypos + 1), 50, 32, memposcolor, memposcolorsmooth, BackgroundColor, 16); + memoryposold = memorypos; + } else { + if (advancedRDS) tftPrint16(ALEFT, String(memorypos + 1), 215, 36, BackgroundColor, BackgroundColor); + else tftPrint16(ALEFT, String(memorypos + 1), 50, 32, BackgroundColor, BackgroundColor); + } +} + +void DoMemoryPosTune() { + radio.clearRDS(); + + if (IsStationEmpty()) { + memoryposstatus = MEM_DARK; + return; + } else memoryposstatus = MEM_NORMAL; + + if (band != presets[memorypos].band) { + band = presets[memorypos].band; + SelectBand(); + } else band = presets[memorypos].band; + + switch (band) { + case BAND_FM: + frequency = presets[memorypos].frequency; + radio.SetFreq(frequency); + break; + case BAND_OIRT: + frequency_OIRT = presets[memorypos].frequency; + radio.SetFreq(frequency_OIRT); + break; + case BAND_LW: + frequency_LW = presets[memorypos].frequency; + radio.SetFreqAM(frequency_LW); + break; + case BAND_MW: + frequency_MW = presets[memorypos].frequency; + radio.SetFreqAM(frequency_MW); + break; + case BAND_SW: + frequency_SW = presets[memorypos].frequency; + radio.SetFreqAM(frequency_SW); + break; + } + + if (band == BAND_FM || band == BAND_OIRT) { + StereoToggle = presets[memorypos].ms; + if (!StereoToggle) { + Stereostatusold = false; + tft.drawBitmap(32, 5, Stereo, 32, 22, BackgroundColor); + tft.drawBitmap(38, 5, Mono, 22, 22, SecondaryColor); + } else { + Stereostatusold = false; + tft.drawBitmap(38, 5, Mono, 22, 22, BackgroundColor); + tft.drawBitmap(32, 5, Stereo, 32, 22, GreyoutColor); + } + } + + if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); + if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); + if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); + + String stationName = ""; + if (presets[memorypos].RDSPS[0] != '\0') { + for (byte i = 0; i < 9; i++) stationName += presets[memorypos].RDSPS[i]; + } + + if (presets[memorypos].RDSPI[0] != '\0') { + for (byte i = 0; i < 4; i++) radio.rds.picode[i] = presets[memorypos].RDSPI[i]; + radio.rds.picode[4] = ' '; + radio.rds.picode[5] = ' '; + radio.rds.picode[6] = '\0'; + radio.rds.correctPI = (uint16_t)strtol(radio.rds.picode, NULL, 16); + } else { + for (byte i = 0; i < 6; i++) radio.rds.picode[i] = '\0'; + } + + radio.rds.stationName = stationName; + + BWset = presets[memorypos].bw; + doBW(); + memtune = true; + memreset = true; + rdsflagreset = false; + findMemoryAF = true; + ShowFreq(0); +} + +void ShowFreq(int mode) { + if (!setupmode) { + if (band != BAND_FM && band != BAND_OIRT) { + if (freqold < 2000 && frequency_AM >= 2000 && stepsize == 0) if (frequency_AM != 27000 && freqold != 144) radio.SetFreqAM(2000); + if (freqold >= 2000 && frequency_AM < 2000 && stepsize == 0) if (frequency_AM != 144 && freqold != 27000) radio.SetFreqAM(1998); + } + } + + if (band > BAND_GAP) { + switch (band) { + case BAND_LW: frequency_AM = frequency_LW; break; + case BAND_MW: frequency_AM = frequency_MW; break; + case BAND_SW: frequency_AM = frequency_SW; break; + } + + if (!screenmute) { + FrequencySprite.fillSprite(BackgroundColor); + FrequencySprite.setTextDatum(TR_DATUM); + FrequencySprite.setTextColor(FreqColor, FreqColorSmooth, false); + FrequencySprite.drawString(String(frequency_AM) + " ", 218, -6, freqfont); + FrequencySprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); + FrequencySprite.setTextDatum(TL_DATUM); + + if (band == BAND_SW && showSWMIBand) { + DivdeSWMIBand(); + updateSWMIBand(); + } + + FrequencySprite.pushSprite(46, 46); + } + + freqold = frequency_AM; + } else { + unsigned int freq = 0; + if (band == BAND_FM) freq = frequency + ConverterSet * 100; + if (band == BAND_OIRT) freq = frequency_OIRT; + + if (!screenmute) { + if (advancedRDS) { + for (int i = 0; i < 33; i++) tft.fillCircle((6 * i) + 10, 133, 2, GreyoutColor); + tftReplace(ARIGHT, String(freqold / 100) + "." + (freqold % 100 < 10 ? "0" : "") + String(freqold % 100), String(freq / 100) + "." + (freq % 100 < 10 ? "0" : "") + String(freq % 100), 273, 35, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); + freqold = freq; + } else if (afscreen) { + tftReplace(ARIGHT, String(freqold / 100) + "." + (freqold % 100 < 10 ? "0" : "") + String(freqold % 100) + " MHz", String(freq / 100) + "." + (freq % 100 < 10 ? "0" : "") + String(freq % 100), 290, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16); + freqold = freq; + } else { + FrequencySprite.fillSprite(BackgroundColor); + + if (mode == 0) { + FrequencySprite.setTextDatum(TR_DATUM); + FrequencySprite.setTextColor(FreqColor, FreqColorSmooth, false); + } else { + FrequencySprite.setTextDatum(TC_DATUM); + FrequencySprite.setTextColor(ActiveColor, ActiveColorSmooth, false); + } + + switch (mode) { + case 0: + FrequencySprite.drawString(String(freq / 100) + "." + (freq % 100 < 10 ? "0" : "") + String(freq % 100) + " ", 218, -6, freqfont); + freqold = freq; + break; + case 1: Infoboxprint(textUI(31)); break; + case 2: Infoboxprint(textUI(286)); break; + case 3: Infoboxprint(textUI(287)); break; + case 4: Infoboxprint(textUI(291)); break; + case 5: Infoboxprint(textUI(280)); break; + } + + FrequencySprite.pushSprite(46, 46); + if (mode == 5) delay(1000); + } + } + } + + rdsreset = true; + afmethodBold = false; + aid_counterold = 0; + dropout = false; + + if (wifi) { + Udp.beginPacket(remoteip, 9030); + if (band == BAND_FM) Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";freq=" + String(frequency) + "0000"); + else if (band == BAND_OIRT) Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";freq=" + String(frequency_OIRT) + "0000"); + else Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";freq=" + String(frequency_AM) + "000"); + Udp.endPacket(); + } + tuningtimer = millis(); + + if (!rdsflagreset && !screenmute && !afscreen && !rdsstatscreen) { + ShowRDSLogo(false); + if (!advancedRDS) { + FullLineSprite.fillSprite(BackgroundColor); + FullLineSprite.drawLine(283, 0, 283, 19, FrameColor); + FullLineSprite.pushSprite(36, 220); + tft.fillCircle(314, 223, 2, GreyoutColor); + tft.fillCircle(314, 234, 2, GreyoutColor); + } else { + GeneralTextSprite.fillSprite(TFT_TRANSPARENT); + GeneralTextSprite.fillRect(0, 0, 165, 19, BackgroundColor); + GeneralTextSprite.pushSprite(36, 220, TFT_TRANSPARENT); + tft.fillCircle(314, 223, 2, GreyoutColor); + tft.fillCircle(314, 234, 2, GreyoutColor); + } + rdsflagreset = true; + } +} + +void ShowSignalLevel() { + SAvg = (((SAvg * 9) + 5) / 10) + SStatus; + SAvg2 = (((SAvg2 * 9) + 5) / 10) + CN; + SAvg4 = (((SAvg4 * 9) + 5) / 10) + WAM; + SAvg5 = (((SAvg5 * 9) + 5) / 10) + USN; + + SStatus = SAvg / 10; + CN = SAvg2 / 10; + MP = SAvg4 / 10; + US = SAvg5 / 10; + + if (!screenmute) { + if (millis() >= SNRupdatetimer + TIMER_SNR_TIMER) { + SNRupdatetimer = millis(); + if (!advancedRDS) { + if (CN > (CNold + 1) || CN < (CNold - 1)) { + if (CNold == 0) tftPrint16(ARIGHT, "--", 234, 165, BackgroundColor, BackgroundColor); else tftPrint16(ARIGHT, String(CNold), 234, 165, BackgroundColor, BackgroundColor); + if (tuned) { + if (CN == 0) tftPrint16(ARIGHT, "--", 234, 165, PrimaryColor, PrimaryColorSmooth); else tftPrint16(ARIGHT, String(CN), 234, 165, PrimaryColor, PrimaryColorSmooth); + CNold = CN; + } else { + tftPrint16(ARIGHT, "--", 234, 165, PrimaryColor, PrimaryColorSmooth); + CNold = 0; + } + } + + byte MPprint = constrain(map(MP, 0, 1000, 0, 100), 0, 100); + if (MPprint != MPold) { + tftReplace(ARIGHT, String(MPold), (band < BAND_GAP ? String(MPprint) : "--"), 299, 165, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); + MPold = MPprint; + } + + byte USprint = constrain(map(US, 0, 1000, 0, 100), 0, 100); + if (USprint != USold) { + tftReplace(ARIGHT, String(USold), (band < BAND_GAP ? String(USprint) : "--"), 299, 147, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); + USold = USprint; + } + } + } + + int SStatusprint = 0; + if (unit == 0) SStatusprint = SStatus; + if (unit == 1) SStatusprint = ((SStatus * 100) + 10875) / 100; + if (unit == 2) SStatusprint = round((float(SStatus) / 10.0 - 10.0 * log10(75) - 90.0) * 10.0); + + static int DisplayedSignalSegments = 0; + if (SStatusprint > (SStatusold + 3) || SStatusprint < (SStatusold - 3)) { + if (advancedRDS) tftReplace(ARIGHT, String(SStatusold / 10) + "." + String(abs(SStatusold % 10)), String(SStatusprint / 10) + "." + String(abs(SStatusprint % 10)), 273, 51, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); + else { + if (SStatusold / 10 != SStatusprint / 10) tftReplace(ARIGHT, String(SStatusold / 10), String(SStatusprint / 10), 280, 104, FreqColor, FreqColorSmooth, BackgroundColor, 48); + tftReplace(ALEFT, "." + String(abs(SStatusold % 10)), "." + String(abs(SStatusprint % 10)), 285, 102, FreqColor, FreqColorSmooth, BackgroundColor, 28); + + // Calculate segments for signal meter + if (band < BAND_GAP) DisplayedSignalSegments = constrain(map(SStatus / 10, 0, 70, 0, 100), 0, 87); + else DisplayedSignalSegments = constrain((SStatus + 200) / 10, 0, 87); + + HSV hsv1 = RGB565toHSV(BarInsignificantColor); + HSV hsv2 = RGB565toHSV(BarSignificantColor); + + int gradientStart = (87 * 25) / 100; + int gradientEnd = (87 * 60) / 100; + + // Draw solid color for first 25% + for (int i = 0; i < min(DisplayedSignalSegments, gradientStart); i++) tft.fillRect(16 + 2 * i, 105, 2, 6, BarInsignificantColor); + + if (DisplayedSignalSegments > gradientStart) { + for (int i = gradientStart; i < min(DisplayedSignalSegments, gradientEnd); i++) { + float h = map(i, gradientStart, gradientEnd, hsv1.h, hsv2.h); + float s = map(i, gradientStart, gradientEnd, hsv1.s * 100, hsv2.s * 100) / 100.0; + float v = map(i, gradientStart, gradientEnd, hsv1.v * 100, hsv2.v * 100) / 100.0; + tft.fillRect(16 + 2 * i, 105, 2, 6, HSVtoRGB565(h, s, v)); + } + } + + if (DisplayedSignalSegments > gradientEnd) { + for (int i = gradientEnd; i < DisplayedSignalSegments; i++) tft.fillRect(16 + 2 * i, 105, 2, 6, BarSignificantColor); + } + + int greyStart = 16 + 2 * DisplayedSignalSegments; + int greyWidth = 2 * (87 - DisplayedSignalSegments); + tft.fillRect(greyStart, 105, greyWidth, 6, GreyoutColor); + } + + SStatusold = SStatusprint; + } + } + + if (!seek) { + if (tuned && CN > 15 && SStatus > 300) { + if (!setextendbw) { + setextendbw = true; + radio.extendBW(true); + } + } else { + if (setextendbw) { + setextendbw = false; + radio.extendBW(false); + } + } + } + + if (wifi && millis() >= udptimer + 2000) { + udptimer = millis(); + Udp.beginPacket(remoteip, 9030); + Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";RcvLevel=" + String(SStatus / 10)); + Udp.endPacket(); + } +} + +void ShowOffset() { + if (OStatus != OStatusold) { + if (millis() >= offsetupdatetimer + TIMER_OFFSET_TIMER) offsetupdatetimer = millis(); + else return; + + int baseX = 13; // Left boundary + int baseY = 2; // Top boundary + int width = 4; // Max width + int height = 26; // Max height + + int centerX = baseX + width / 2; // Center dot X + int centerY = baseY + height / 2; // Center dot Y + + // **Move arrows 3px further from the dot** + int arrowGap = 3; // Space between dot and arrows + int arrowWidth = 9; // Arrow stretch size + int leftArrowBaseX = centerX - arrowWidth - arrowGap; // Shift left arrow further left + int rightArrowBaseX = centerX + arrowWidth + arrowGap; // Shift right arrow further right + + int arrowBaseYTop = baseY + 1; // Adjusted top Y position + int arrowBaseYBottom = baseY + height - 1; + + if (band < BAND_GAP) { + if (OStatus < -250) { + // Left arrow active (▶) + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); + // Center dot + tft.fillCircle(centerX, centerY, 3, GreyoutColor); + // Right arrow dimmed (◀) + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, SignificantColor); + tuned = false; + } else if (USN < 250 && WAM < 250 && OStatus > -250 && OStatus < 250 && !SQ) { + // Both arrows dimmed + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); + // Center dot active + tft.fillCircle(centerX, centerY, 3, InsignificantColor); + tuned = true; + } else if (OStatus > 250) { + // Right arrow active (◀) + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); + // Center dot dimmed + tft.fillCircle(centerX, centerY, 3, GreyoutColor); + // Left arrow dimmed (▶) + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, SignificantColor); + tuned = false; + } else { + // Everything dimmed + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillCircle(centerX, centerY, 3, GreyoutColor); + tuned = false; + } + } else { + if (OStatus < -2) { + // Left arrow active (▶) + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillCircle(centerX, centerY, 3, GreyoutColor); + // Right arrow dimmed (◀) + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, SignificantColor); + tuned = false; + } else if (OStatus >= -2 && OStatus <= 2 && !SQ) { + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillCircle(centerX, centerY, 3, InsignificantColor); + tuned = true; + } else if (OStatus > 2) { + // Right arrow active (◀) + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillCircle(centerX, centerY, 3, GreyoutColor); + // Left arrow dimmed (▶) + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, SignificantColor); + tuned = false; + } else { + tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); + tft.fillCircle(centerX, centerY, 3, GreyoutColor); + tuned = false; + } + } + OStatusold = OStatus; + } +} + +void ShowAudioLevel() { + if(showaudio) { + int segments; + MStatus = (MStatus > 120) ? 120 : MStatus; + + if (seek || SQ) MStatus = 0; + + segments = constrain(map(MStatus, 0, 120, 0, 86), 0, 86); + + if (segments < DisplayedSegments && (millis() - AudiopreviousMillis >= 20)) { + DisplayedSegments = max(DisplayedSegments - 3, segments); + AudiopreviousMillis = millis(); + } else if (segments > DisplayedSegments) DisplayedSegments = segments; + + DisplayedSegments = constrain(DisplayedSegments, 0, 86); + + if (DisplayedSegments > peakholdold) { + peakholdold = DisplayedSegments; + peakholdmillis = millis(); + } + + if (millis() - peakholdmillis >= 1000) { + if (millis() - AudiopeakPreviousMillis >= 20) { + peakholdold = max(peakholdold - 3, DisplayedSegments); + AudiopeakPreviousMillis = millis(); + } + } + + peakholdold = constrain(peakholdold, 0, 86); + + HSV hsv1 = RGB565toHSV(ModBarInsignificantColor); + HSV hsv2 = RGB565toHSV(ModBarSignificantColor); + + int gradientStart = (86 * 25) / 100; + int gradientEnd = (86 * 60) / 100; + + for (int i = 0; i < min(DisplayedSegments, gradientStart); i++) tft.fillRect(16 + 2 * i, 133, 2, 6, ModBarInsignificantColor); + + if (DisplayedSegments > gradientStart) { + for (int i = gradientStart; i < min(DisplayedSegments, gradientEnd); i++) { + float h = map(i, gradientStart, gradientEnd, hsv1.h, hsv2.h); + float s = map(i, gradientStart, gradientEnd, hsv1.s * 100, hsv2.s * 100) / 100.0; + float v = map(i, gradientStart, gradientEnd, hsv1.v * 100, hsv2.v * 100) / 100.0; + tft.fillRect(16 + 2 * i, 133, 2, 6, HSVtoRGB565(h, s, v)); + } + } + + if (DisplayedSegments > gradientEnd) { + for (int i = gradientEnd; i < DisplayedSegments; i++) tft.fillRect(16 + 2 * i, 133, 2, 6, ModBarSignificantColor); + } + + int greyStart = 16 + 2 * DisplayedSegments; + int greyWidth = 2 * (87 - DisplayedSegments); + tft.fillRect(greyStart, 133, greyWidth, 6, GreyoutColor); + + int peakHoldPosition = 16 + 2 * peakholdold; + tft.fillRect(peakHoldPosition, 133, 2, 6, (MStatus > 80) ? ModBarSignificantColor : PrimaryColor); + + if (millis() - peakholdmillis >= 1000 && (peakholdold <= DisplayedSegments || peakholdold >= 86)) tft.fillRect(peakHoldPosition, 133, 2, 6, GreyoutColor); + } +} + +void doSquelch() { + if (!XDRGTKUSB && !XDRGTKTCP && usesquelch && !autosquelch) Squelch = map(analogRead(PIN_POT), 0, 4095, -100, 920); + if (Squelch < - 800) Squelch = -100; + if (Squelch > 900) Squelch = 920; + + if (unit == 0) SquelchShow = Squelch / 10; + if (unit == 1) SquelchShow = ((Squelch * 100) + 10875) / 1000; + if (unit == 2) SquelchShow = round(((float)Squelch / 10.0 - 10.0 * log10(75) - 90.0) * 10.0) / 10; + if (Squelch > 920) Squelch = 920; + + if (autosquelch) { + if (band < BAND_GAP) { + if (isSignalQualityGood(USN, WAM, OStatus, SCAN_SIGNAL_THRESHOLD_USN_MULTIPLIER, SCAN_SIGNAL_THRESHOLD_OSTATUS_WIDE) && (!scandxmode || (scandxmode && !scanmute))) { + if (SQ || BWreset) { + if (!seek) radio.setUnMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + autosquelchtimer = millis(); + SQ = false; + } + } else { + if ((!SQ || BWreset) && (millis() >= autosquelchtimer + 1000)) { + radio.setMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + autosquelchtimer = millis(); + SQ = true; + } + } + } else { + if ((USN < amscansens * 30) && (OStatus < 2 && OStatus > -2) && (!scandxmode || (scandxmode && !scanmute))) { + if (!seek) radio.setUnMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + SQ = false; + } else { + radio.setMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + SQ = true; + } + } + } else { + if (!XDRGTKUSB && !XDRGTKTCP && usesquelch && (!scandxmode || (scandxmode && !scanmute))) { + if (!screenmute && usesquelch && !advancedRDS && !afscreen && !rdsstatscreen) { + if (!BWtune && !menu && (Squelch > Squelchold + 2 || Squelch < Squelchold - 2)) { + SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); + SquelchSprite.fillSprite(BackgroundColor); + if (Squelch == -100) SquelchSprite.drawString("--", 0, 0); + else if (Squelch == 920) SquelchSprite.drawString("ST", 0, 0); + else SquelchSprite.drawString(String(SquelchShow), 0, 0); + SquelchSprite.pushSprite(223, 147); + Squelchold = Squelch; + } + } + } + + if ((XDRGTKUSB || XDRGTKTCP) && (!scandxmode || (scandxmode && !scanmute))) { + if (!XDRMute) { + if (Squelch != -1) { + if (Squelch < SStatus || Squelch == -100 || Squelch == 0) { + if (!seek) radio.setUnMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + SQ = false; + } else { + radio.setMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + SQ = true; + } + } else { + if (Stereostatus) { + radio.setUnMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + SQ = false; + } else { + radio.setMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + SQ = true; + } + } + if (!screenmute && usesquelch && !advancedRDS && !afscreen && !rdsstatscreen) { + if (Squelch != Squelchold) { + SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth); + SquelchSprite.fillSprite(BackgroundColor); + + if (Squelch == -1) SquelchSprite.drawString("ST", 0, 0); + else if (Squelch == 0) SquelchSprite.drawString("--", 0, 0); + else SquelchSprite.drawString(String(SquelchShow), 0, 0); + if (Squelch != Squelchold) SquelchSprite.pushSprite(223, 147); + Squelchold = Squelch; + } + } + } + } else if (usesquelch && (!scandxmode || (scandxmode && !scanmute))) { + if (Squelch != 920) { + if (Squelch < SStatus || Squelch == -100 || Squelch == 0) { + if (!seek) radio.setUnMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + SQ = false; + } else { + radio.setMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + SQ = true; + } + } else { + if (Stereostatus) { + if (!seek) radio.setUnMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + SQ = false; + } else { + radio.setMute(); + if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + SQ = true; + } + } + } + } +} + +void doBW() { + if (BWtune && !bwtouchtune) BWset = BWsettemp; + + if (band < BAND_GAP) { + if (BWset > 16) BWset = 0; + + switch (BWset) { + case 1: radio.setFMBandw(56); break; + case 2: radio.setFMBandw(64); break; + case 3: radio.setFMBandw(72); break; + case 4: radio.setFMBandw(84); break; + case 5: radio.setFMBandw(97); break; + case 6: radio.setFMBandw(114); break; + case 7: radio.setFMBandw(133); break; + case 8: radio.setFMBandw(151); break; + case 9: radio.setFMBandw(168); break; + case 10: radio.setFMBandw(184); break; + case 11: radio.setFMBandw(200); break; + case 12: radio.setFMBandw(217); break; + case 13: radio.setFMBandw(236); break; + case 14: radio.setFMBandw(254); break; + case 15: radio.setFMBandw(287); break; + case 16: radio.setFMBandw(311); break; + } + BWsetFM = BWset; + EEPROM.writeByte(EE_BYTE_BWSET_FM, BWsetFM); + + if ((XDRGTKUSB || XDRGTKTCP) && !XDRScan) { + switch (BWset) { + case 0: DataPrint("W0\n"); break; + case 1: DataPrint("W56000\n"); break; + case 2: DataPrint("W64000\n"); break; + case 3: DataPrint("W72000\n"); break; + case 4: DataPrint("W84000\n"); break; + case 5: DataPrint("W97000\n"); break; + case 6: DataPrint("W114000\n"); break; + case 7: DataPrint("W133000\n"); break; + case 8: DataPrint("W151000\n"); break; + case 9: DataPrint("W168000\n"); break; + case 10: DataPrint("W184000\n"); break; + case 11: DataPrint("W200000\n"); break; + case 12: DataPrint("W217000\n"); break; + case 13: DataPrint("W236000\n"); break; + case 14: DataPrint("W254000\n"); break; + case 15: DataPrint("W287000\n"); break; + case 16: DataPrint("W311000\n"); break; + } + } + } else { + if (BWset > 4) BWset = 1; + + switch (BWset) { + case 1: radio.setAMBandw(3); break; + case 2: radio.setAMBandw(4); break; + case 3: radio.setAMBandw(6); break; + case 4: radio.setAMBandw(8); break; + } + BWsetAM = BWset; + EEPROM.writeByte(EE_BYTE_BWSET_AM, BWsetAM); + } + updateBW(); + BWreset = true; + EEPROM.commit(); +} + +void doTuneMode() { + switch (tunemode) { + case TUNE_MAN: + if (band == BAND_SW) { + if (showSWMIBand && nowToggleSWMIBand) tunemode = TUNE_MI_BAND; + else tunemode = TUNE_AUTO; + } else tunemode = TUNE_AUTO; + break; + case TUNE_MI_BAND: + case TUNE_AUTO: + tunemode = TUNE_MEM; + break; + case TUNE_MEM: + if (!bandforbidden) tunemode = TUNE_MAN; + break; + } + ShowTuneMode(); + ShowMemoryPos(); + EEPROM.writeByte(EE_BYTE_TUNEMODE, tunemode); + EEPROM.commit(); +} + +void ShowTuneMode() { + if (!screenmute) { + switch (tunemode) { + case TUNE_MAN: + if (band == BAND_SW && nowToggleSWMIBand) { + tftPrint16(ACENTER, "AUTO", 22, 60, GreyoutColor, GreyoutColor); + tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, GreyoutColor); + } else { + tftPrint16(ACENTER, "BAND", 22, 60, GreyoutColor, GreyoutColor); + tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, GreyoutColor); + } + + tft.fillRoundRect(2, 36, 40, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, SecondaryColor); + + tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); + break; + + case TUNE_AUTO: + tft.fillRoundRect(2, 58, 40, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, SecondaryColor); + + tft.fillRoundRect(2, 36, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, GreyoutColor); + + tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); + break; + + case TUNE_MEM: + if (band == BAND_SW && nowToggleSWMIBand) { + tftPrint16(ACENTER, "AUTO", 22, 60, GreyoutColor, GreyoutColor); + + tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, GreyoutColor); + } else { + tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, GreyoutColor); + + tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, GreyoutColor); + } + + tft.fillRoundRect(2, 36, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, GreyoutColor); + + if (memorystore) { + tft.fillRoundRect(2, 80, 40, 18, 2, SignificantColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SignificantColor); + } else { + tft.fillRoundRect(2, 80, 40, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SecondaryColor); + } + break; + + case TUNE_MI_BAND: + tft.fillRoundRect(2, 58, 40, 18, 2, SecondaryColor); + tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, SecondaryColor); + + tft.fillRoundRect(2, 36, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, GreyoutColor); + + tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); + tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); + break; + } + } +} + +void ShowBattery() { + if (millis() >= batupdatetimer + TIMER_BAT_TIMER) batupdatetimer = millis(); + else return; + + float v = analogReadMilliVolts(BATTERY_PIN) * 0.002; // 0.002 converts to volts plus corrects the /2 voltage divider + byte battery = map(constrain(v, BATTERY_LOW_VALUE, BATTERY_FULL_VALUE), BATTERY_LOW_VALUE, BATTERY_FULL_VALUE, 0, BAT_LEVEL_STAGE); + byte batteryprobe = map(constrain(v, BATTERY_LOW_VALUE, BATTERY_FULL_VALUE), BATTERY_LOW_VALUE, BATTERY_FULL_VALUE, 0, 50); + if (batteryold != batteryprobe) { + if (batterydetect) { + if (battery == 0) { + tft.drawRoundRect(277, 6, 37, 20, 2, BarSignificantColor); + tft.fillRoundRect(313, 13, 4, 6, 2, BarSignificantColor); + } else { + tft.drawRoundRect(277, 6, 37, 20, 2, ActiveColor); + tft.fillRoundRect(313, 13, 4, 6, 2, ActiveColor); + } + + if (batteryoptions != BATTERY_VALUE && batteryoptions != BATTERY_PERCENT && battery != 0) { + if(v > BATTERY_FULL_VALUE) tft.fillRoundRect(279, 8, 32, 16, 2, ActiveColor); + else tft.fillRoundRect(279, 8, battery * 8, 16, 2, SecondaryColor); + } else tft.fillRoundRect(279, 8, 32, 16, 2, BackgroundColor); + } + batteryold = batteryprobe; + batteryVold = 0; + vPerold = 0; + + if (batterydetect) { + float vPer = constrain((v - BATTERY_LOW_VALUE) / (BATTERY_FULL_VALUE - BATTERY_LOW_VALUE), 0.0, 1.0) * 100.0; + if (abs(v - batteryVold) > 0.05 && batteryoptions == BATTERY_VALUE) { + tftPrint(ALEFT, String(v, 2) + "V", 279, 9, BatteryValueColor, BatteryValueColorSmooth, 16); + batteryVold = v; + } else if (int(vPer) != int(vPerold) && batteryoptions == BATTERY_PERCENT && abs(vPer - vPerold) > 0.5) { + tftPrint(ALEFT, String(vPer, 0) + "%", 279, 9, BatteryValueColor, BatteryValueColorSmooth, 16); + vPerold = vPer; + } + } + } +} + +void TuneUp() { + aftest = true; + aftimer = millis(); + unsigned int temp = 0; + if (stepsize == 0) { + if (band > BAND_GAP) { + if (frequency_AM <= MWHighEdgeSet && frequency_AM >= MWLowEdgeSet) { + if (!mwstepsize) { + temp = FREQ_MW_STEP_9K; + frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; + } else if (mwstepsize) { + temp = FREQ_MW_STEP_10K; + frequency_AM = (frequency_AM / FREQ_MW_STEP_10K) * FREQ_MW_STEP_10K; + } + } else if (frequency_AM < MWLowEdgeSet) { + temp = FREQ_MW_STEP_9K; + frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; + } else if (frequency_AM <= SWHighEdgeSet && frequency_AM >= SWLowEdgeSet) { + temp = FREQ_SW_STEP_5K; + frequency_AM = (frequency_AM / FREQ_SW_STEP_5K) * FREQ_SW_STEP_5K; + } + } else { + if (band == BAND_OIRT) temp = FREQ_OIRT_STEP_30K; + else { + switch (fmdefaultstepsize) { + case 0: temp = FREQ_FM_STEP_50K; break; + case 1: temp = FREQ_FM_STEP_100K; break; + case 2: temp = FREQ_FM_STEP_200K; break; + } + } + } + } + if(stepsize == 1) temp = 1; + else if(stepsize == 2) temp = 10; + else if(stepsize == 3) temp = 100; + else if(stepsize == 4) temp = 1000; + if(rotaryaccelerate && rotarycounter > 2) temp *= 2; + + if (band == BAND_FM) { + frequency += temp; + if (scandxmode) { + while (IsFrequencyUsed(frequency) || presets[memorypos].band != BAND_FM) frequency += temp; + } + + if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8795) frequency = 8790; + if (frequency >= (HighEdgeSet * 10) + 1) { + frequency = LowEdgeSet * 10; + if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8750) frequency = 8775; + EdgeBeeper(); + } + radio.SetFreq(frequency); + } else if (band == BAND_OIRT) { + frequency_OIRT += temp; + if (scandxmode) { + while (IsFrequencyUsed(frequency_OIRT) || presets[memorypos].band != BAND_OIRT) frequency_OIRT += temp; + } + if (frequency_OIRT > HighEdgeOIRTSet) { + frequency_OIRT = LowEdgeOIRTSet; + EdgeBeeper(); + } + radio.SetFreq(frequency_OIRT); + } else if (band == BAND_LW) { + frequency_AM += temp; + if (frequency_AM > LWHighEdgeSet) { + frequency_AM = LWLowEdgeSet; + EdgeBeeper(); + } + radio.SetFreqAM(frequency_AM); + frequency_LW = frequency_AM; + } else if (band == BAND_MW) { + frequency_AM += temp; + if (frequency_AM > MWHighEdgeSet) { + frequency_AM = MWLowEdgeSet; + EdgeBeeper(); + } + radio.SetFreqAM(frequency_AM); + frequency_MW = frequency_AM; + } else if (band == BAND_SW) { + if (rotaryaccelerate && rotarycounter > 2) temp *= 2; + frequency_AM += temp; + if (frequency_AM > SWHighEdgeSet) { + frequency_AM = SWLowEdgeSet; + EdgeBeeper(); + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + } + radio.clearRDS(); + if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); + if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); +} + +void TuneDown() { + aftest = true; + aftimer = millis(); + unsigned int temp = 0; + if (stepsize == 0) { + if (band > BAND_GAP) { + if (frequency_AM < MWHighEdgeSet && frequency_AM > MWLowEdgeSet) { + if (!mwstepsize) { + temp = FREQ_MW_STEP_9K; + frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; + } else if (mwstepsize) { + temp = FREQ_MW_STEP_10K; + frequency_AM = (frequency_AM / FREQ_MW_STEP_10K) * FREQ_MW_STEP_10K; + } + } else if (frequency_AM < MWLowEdgeSet) { + temp = FREQ_MW_STEP_9K; + frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; + } else { + temp = FREQ_SW_STEP_5K; + frequency_AM = (frequency_AM / FREQ_SW_STEP_5K) * FREQ_SW_STEP_5K; + } + } else { + if (band == BAND_OIRT) temp = FREQ_OIRT_STEP_30K; + else { + switch (fmdefaultstepsize) { + case 0: temp = FREQ_FM_STEP_50K; break; + case 1: temp = FREQ_FM_STEP_100K; break; + case 2: temp = FREQ_FM_STEP_200K; break; + } + } + } + } + if (stepsize == 1) temp = 1; + else if (stepsize == 2) temp = 10; + else if (stepsize == 3) temp = 100; + else if (stepsize == 4) temp = 1000; + if (rotaryaccelerate && rotarycounter > 2) temp *= 2; + + if (band == BAND_FM) { + frequency -= temp; + if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8770) frequency = 8775; + if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8755) frequency = 10790; + + if (frequency < LowEdgeSet * 10) { + frequency = HighEdgeSet * 10; + if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 10800) frequency = 10790; + EdgeBeeper(); + } + radio.SetFreq(frequency); + } else if (band == BAND_OIRT) { + frequency_OIRT -= temp; + if (frequency_OIRT < LowEdgeOIRTSet) { + frequency_OIRT = HighEdgeOIRTSet; + EdgeBeeper(); + } + radio.SetFreq(frequency_OIRT); + } else if (band == BAND_LW) { + frequency_AM -= temp; + if (frequency_AM < LWLowEdgeSet) { + frequency_AM = LWHighEdgeSet; + EdgeBeeper(); + } + radio.SetFreqAM(frequency_AM); + frequency_LW = frequency_AM; + } else if (band == BAND_MW) { + frequency_AM -= temp; + if (frequency_AM < MWLowEdgeSet) { + frequency_AM = MWHighEdgeSet; + EdgeBeeper(); + } + radio.SetFreqAM(frequency_AM); + frequency_MW = frequency_AM; + } else if (band == BAND_SW) { + if (rotaryaccelerate && rotarycounter > 2) temp *= 2; + frequency_AM -= temp; + if (frequency_AM < SWLowEdgeSet) { + frequency_AM = SWHighEdgeSet; + EdgeBeeper(); + } + radio.SetFreqAM(frequency_AM); + frequency_SW = frequency_AM; + } + radio.clearRDS(); + if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); + if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); +} + +void Seek(bool mode) { + radio.setMute(); + if (seekinit) { + if (stepsize != 0) { + stepsize = 0; + RoundStep(); + ShowStepSize(); + } + seekinit = false; + } + + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); + if (!mode) TuneDown(); else TuneUp(); + delay(50); + + ShowFreq(0); + if (XDRGTKUSB || XDRGTKTCP) { + if(band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if(band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); + } + + if (band < BAND_GAP) { + radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + if (isSignalQualityGood(USN, WAM, OStatus) && (!usesquelch || (Squelch < SStatus || Squelch == SQUELCH_MAX_VALUE))) { + seek = false; + radio.setUnMute(); + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + store = true; + } else { + seek = true; + if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); + if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); + } + } else { + radio.getStatusAM(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + if ((USN < amscansens * 30) && (OStatus < 2 && OStatus > -2) && (!usesquelch || (Squelch < SStatus || Squelch == 920))) { + seek = false; + radio.setUnMute(); + if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); + store = true; + } else seek = true; + } +} + +void tftReplace(int8_t offset, const String & textold, const String & text, int16_t x, int16_t y, int color, int smoothcolor, int background, uint8_t fontsize) { + uint8_t selectedFont = 0 ? (language == LANGUAGE_CHS) : 2; + if(fontsize == 28) selectedFont = (language == LANGUAGE_CHS) ? 4 : 3; + else if(fontsize == 48) selectedFont = 1; + + switch (offset) { + case -1: tft.setTextDatum(TL_DATUM); break; + case 0: tft.setTextDatum(TC_DATUM); break; + case 1: tft.setTextDatum(TR_DATUM); break; + } + + tft.setTextColor(background, background, false); + tft.drawString(textold, x, y, selectedFont); + + String modifiedText = text; + modifiedText.replace("\n", " "); + + tft.setTextColor(color, smoothcolor, false); + tft.drawString(modifiedText, x, y, selectedFont); +} + +void tftReplace16(int8_t offset, const String & textold, const String & text, int16_t x, int16_t y, int color, int smoothcolor, int background, bool force_font, bool font) { + uint8_t selectedFont = (language == LANGUAGE_CHS) ? 0 : 2; + if(force_font) selectedFont = 0 ? font : 2; + + switch (offset) { + case -1: tft.setTextDatum(TL_DATUM); break; + case 0: tft.setTextDatum(TC_DATUM); break; + case 1: tft.setTextDatum(TR_DATUM); break; + } + + tft.setTextColor(background, background, false); + tft.drawString(textold, x, y, selectedFont); + + String modifiedText = text; + modifiedText.replace("\n", " "); + + tft.setTextColor(color, smoothcolor, false); + tft.drawString(modifiedText, x, y, selectedFont); +} + +void tftPrint(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, uint8_t fontsize) { + uint8_t selectedFont = (language == LANGUAGE_CHS) ? 0 : 2; + if (fontsize == 28) selectedFont = (language == LANGUAGE_CHS) ? 4 : 3; + else if (fontsize == 48) selectedFont = 1; + + tft.setTextColor(color, smoothcolor); + + switch (offset) { + case -1: tft.setTextDatum(TL_DATUM); break; + case 0: tft.setTextDatum(TC_DATUM); break; + case 1: tft.setTextDatum(TR_DATUM); break; + } + + String modifiedText = text; + modifiedText.replace("\n", " "); + + tft.drawString(modifiedText, x, y, selectedFont); +} + +void tftPrint16(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, bool force_font, bool font) { + uint8_t selectedFont = (language == LANGUAGE_CHS) ? 0 : 2; + if(force_font) selectedFont = 0 ? font : 2; + + tft.setTextColor(color, smoothcolor); + + switch (offset) { + case -1: tft.setTextDatum(TL_DATUM); break; + case 0: tft.setTextDatum(TC_DATUM); break; + case 1: tft.setTextDatum(TR_DATUM); break; + } + + String modifiedText = text; + modifiedText.replace("\n", " "); + + tft.drawString(modifiedText, x, y, selectedFont); +} + +void UpdateFonts() { + // This is at setup: + // tft.loadFont(FONT48, 1); + + // tft.loadFont(FONT16_CHS, 0); + // tft.loadFont(FONT16, 2); + // tft.loadFont(FONT28, 3); + // tft.loadFont(FONT28_CHS, 4); + + if (language == LANGUAGE_CHS) { + if (menu) PSSprite.setTextFont(1); else PSSprite.setTextFont(3); + OneBigLineSprite.copyFontFromTFT(4, 0); + FullLineSprite.copyFontFromTFT(0, 0); + GeneralTextSprite.copyFontFromTFT(0, 0); + GeneralTextSprite.copyFontFromTFT(4, 1); + FrequencySprite.copyFontFromTFT(0, 6); + SquelchSprite.copyFontFromTFT(0, 0); + } else { + if (menu) PSSprite.setTextFont(0); else PSSprite.setTextFont(2); + OneBigLineSprite.copyFontFromTFT(3, 0); + FullLineSprite.copyFontFromTFT(2, 0); + GeneralTextSprite.copyFontFromTFT(2, 0); + GeneralTextSprite.copyFontFromTFT(3, 1); + FrequencySprite.copyFontFromTFT(2, 6); + SquelchSprite.copyFontFromTFT(2, 0); + } +} + +uint8_t doAutoMemory(uint16_t startfreq, uint16_t stopfreq, uint8_t startmem, uint8_t stopmem, bool rdsonly, uint8_t doublepi) { + uint8_t error = 0; + uint8_t counter = 0; + uint8_t rangestart = startmem; + uint16_t _current = frequency; + uint16_t totalIterations = (stopfreq - startfreq) + 1; + uint16_t currentIteration = 0; + uint8_t percent = 0; + uint8_t percentold = 0; + bool stopScanning = false; + bool dostore = false; + + radio.setMute(); + radio.power(0); + band = BAND_FM; + tunemode = TUNE_MAN; + + tft.drawRect(59, 109, 202, 8, FrameColor); + tft.fillRect(60, 110, 200, 6, GreyoutColor); + tftPrint(ARIGHT, textUI(268), 120, 155, ActiveColor, ActiveColorSmooth, 16); + + for (frequency = startfreq * 10; frequency <= stopfreq * 10; frequency += 10) { + if (stopScanning) break; + + currentIteration++; + percent = (currentIteration * 100) / totalIterations; + + radio.SetFreq(frequency); + radio.clearRDS(); + delay(DELAY_TUNE_MS); + radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); + if (isSignalQualityGood(USN, WAM, OStatus)) { + for (byte y = 0; y < 20; y++) { + delay(DELAY_RDS_READ_MS); + radio.readRDS(showrdserrors); + } + + dostore = true; + if (doublepi != 0) { + for (byte x = (doublepi == 1 ? rangestart : 0); x <= (doublepi == 1 ? stopmem : EE_PRESETS_CNT - 1); x++) { + if (presets[x].RDSPI[0] != '\0') { + bool allMatch = true; + + for (byte i = 0; i < 4; i++) { + if (presets[x].RDSPI[i] != radio.rds.picode[i]) { + allMatch = false; + break; + } + } + + if (allMatch) { + dostore = false; + break; + } + } + } + } + + if (((rdsonly && radio.rds.hasRDS) || !rdsonly) && dostore) { + StoreMemoryPos(startmem); + counter ++; + startmem++; + if (startmem > stopmem) { + error = 1; + stopScanning = true; + break; + } + dostore = false; + } + } + + if (percent != percentold) { + switch (CurrentTheme) { + case 7: + SignalSprite.pushImage(-107, -95, 292, 170, popupbackground_wo); + SquelchSprite.pushImage(-177, -135, 292, 170, popupbackground_wo); + break; + default: + SignalSprite.pushImage(-107, -95, 292, 170, popupbackground); + SquelchSprite.pushImage(-177, -135, 292, 170, popupbackground); + break; + } + + SignalSprite.setTextColor(SecondaryColor, SecondaryColorSmooth, false); + SignalSprite.setTextDatum(TC_DATUM); + SignalSprite.drawString(String(percent) + "%", 40, 0); + SignalSprite.pushSprite(120, 125); + + SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); + SquelchSprite.drawString(String(counter), 0, 0); + SquelchSprite.pushSprite(200, 155); + + tft.fillRect(60, 110, 2 * percent, 6, BarInsignificantColor); + + percentold = percent; + } + if (digitalRead(MODEBUTTON) == LOW) { + while (digitalRead(MODEBUTTON)) delay(50); + error = 2; + stopScanning = true; + break; + } + } + + frequency = _current; + radio.SetFreq(frequency); + radio.clearRDS(); + radio.setUnMute(); + SQ = false; + + return error; +} diff --git a/src/gui.cpp b/src/gui.cpp index 233d582..999d28d 100644 --- a/src/gui.cpp +++ b/src/gui.cpp @@ -6,6 +6,9 @@ extern mem presets[]; bool setWiFiConnectParam = false; +const char* BWButtonLabelsFM[] = {"56 kHz", "64 kHz", "72 kHz", "84 kHz", "97 kHz", "114 kHz", "133 kHz", "151 kHz", "168 kHz", "184 kHz", "200 kHz", "217 kHz", "236 kHz", "254 kHz", "287 kHz", "311 kHz", "Auto", "iMS", "EQ"}; +const char* BWButtonLabelsAM[] = {"3 kHz", "4 kHz", "6 kHz", "8 kHz"}; + void doTheme() { // Use this to put your own colors in: http://www.barth-dev.de/online/rgb565-color-picker/ switch (CurrentTheme) { case 0: // Essence diff --git a/src/logbook.cpp b/src/logbook.cpp index e5530f4..d75e100 100644 --- a/src/logbook.cpp +++ b/src/logbook.cpp @@ -104,7 +104,7 @@ void handleRoot() { String column = header.substring(startIndex, endIndex); if (column.equalsIgnoreCase("PI")) piCodeIndex = columnIndex; - if (column.equalsIgnoreCase("Frequency")) frequencyIndex = columnIndex; + else if (column.equalsIgnoreCase("Frequency")) frequencyIndex = columnIndex; startIndex = endIndex + 1; columnIndex++; @@ -170,9 +170,7 @@ void handleDownloadCSV() { } bool handleCreateNewLogbook() { - if (SPIFFS.exists("/logbook.csv")) { - if (!SPIFFS.remove("/logbook.csv")) return false; - } + if (SPIFFS.exists("/logbook.csv") && !SPIFFS.remove("/logbook.csv")) return false; fs::File file = SPIFFS.open("/logbook.csv", "w"); if (!file) return false; @@ -343,8 +341,7 @@ void printLogbookCSV() { Serial.println("===== Start of logbook.csv ====="); while (file.available()) { - String line = file.readStringUntil('\n'); - Serial.println(line); + Serial.println(file.readStringUntil('\n')); } file.close(); diff --git a/src/main.cpp b/src/main.cpp index ef4e9e1..db41d43 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,269 +1,54 @@ -#pragma region includes -#include "soc/soc.h" -#include "soc/rtc_cntl_reg.h" -#include -#include -#include -using fs::FS; -#include -#include "NTPupdate.h" +#include "globals.h" +#include "core.h" +#include "main.h" +#include "gui.h" +#include "nonvolatile.h" #include "FONT16.h" #include "FONT16_CHS.h" #include "FONT28.h" #include "FONT28_CHS.h" #include "FONT48DEC.h" #include "FREQFONT.h" -#include "globals.h" -#include "gui.h" -#include "comms.h" -#include "rds.h" -#include "touch.h" -#include "nonvolatile.h" -#include "utils.h" -#include "system_console.h" -#include "main.h" -#pragma endregion -Console console(&tft); -RTC_DATA_ATTR bool gpio_chip = false; -RTC_DATA_ATTR bool tef_found = false; - -template -void panic(Args... args) { - radio.power(1); - tft.fillScreen(TFT_RED); - console.reset(); - - (console.print(args), ...); - while (true); -} - -#pragma region helpers -inline bool isSignalQualityGood(int usn, int wam, int ostatus, int threshold_multiplier = SCAN_SIGNAL_THRESHOLD_USN_MULTIPLIER, int ostatus_threshold = SCAN_SIGNAL_THRESHOLD_OSTATUS) { - return (usn < fmscansens * threshold_multiplier) && - (wam < SCAN_SIGNAL_THRESHOLD_WAM) && - (ostatus < ostatus_threshold) && - (ostatus > -ostatus_threshold); -} - -inline void Round30K(unsigned int freq) { - if (freq % FREQ_OIRT_STEP_30K == 1) frequency_OIRT = (freq + 1); - else if (freq % FREQ_OIRT_STEP_30K == 0) frequency_OIRT = (freq - 1); -} - -inline void Round50K(unsigned int freq) { - if (freq % 10 < 3) frequency = (freq - freq % 10); - else if (freq % 10 > 2 && freq % 10 < 8) frequency = (freq - (freq % 10 - 5)); - else if (freq % 10 > 7) frequency = (freq - (freq % 10) + 10); -} - -inline void Round100K(unsigned int freq) { - if (freq % 10 < 5) frequency = (freq - freq % 10); - else frequency = (freq - (freq % 10) + 10); -} - -void Round200K(unsigned int freq) { - frequency = (freq / 10) * 10; - - if (freq % 10 >= 5) frequency += 10; - if ((frequency / 100) % 2 == 0) frequency += 10; - if (frequency > 10800) frequency = 10790; - if (frequency % 20 == 0 && (frequency / 10) % 2 == 0) frequency -= 10; -} - -void Round5K(unsigned int freqAM) { - if (freqAM % 10 < 3) frequency_AM = (freqAM - freqAM % 10); - else if (freqAM % 10 > 2 && freqAM % 10 < 8) frequency_AM = (freqAM - (freqAM % 10 - 5)); - else if (freqAM % 10 > 7) frequency_AM = (freqAM - (freqAM % 10) + 10); -} - -inline void Touch_IRQ_Handler() { +void Touch_IRQ_Handler() { touch_detect = true; } -inline void deepSleep() { - MuteScreen(1); - StoreFrequency(); - radio.power(1); - esp_sleep_enable_ext0_wakeup((gpio_num_t)ROTARY_PIN_A, LOW); - esp_deep_sleep_start(); -} - -inline bool IsStationEmpty() { - return presets[memorypos].band == BAND_FM && presets[memorypos].frequency == EE_PRESETS_FREQUENCY; -} - -void ShowFreq(int mode); -void doLog() { - if (!autologged && RDSstatus && radio.rds.correctPI != 0) { - if (autolog) { - switch (addRowToCSV()) { - case 0: ShowFreq(2); break; - case 1: ShowFreq(3); break; - case 2: ShowFreq(4); break; - } - - delay(DELAY_UI_UPDATE_MS); - ShowFreq(0); - } - autologged = true; - } -} - -inline void EdgeBeeper() { - if(!edgebeep) return; - radio.tone(50, -5, 2000); -} - -const char* textUI(uint16_t number) { - if (number >= language_entrynumber) return "Overflow"; - else return (const char*)pgm_read_ptr(&(myLanguage[language][number])); -} - -inline bool shouldHighlightBWButton(byte temp, byte set) { - return (set == temp) || - (temp == 17 && set == 0) || - (temp == 18 && !iMSset) || - (temp == 19 && !EQset); -} - -inline const char* getBWButtonLabel(byte temp, bool isFM) { - constexpr byte BW_OK_BUTTON = 20; - if (temp == BW_OK_BUTTON) return "OK"; - return isFM ? BWButtonLabelsFM[temp - 1] : BWButtonLabelsAM[temp - 1]; -} - -void doBWtuneUp() { - rotary = 0; - constexpr byte BW_OK_BUTTON = 20; - constexpr byte BW_AM_MAX = 4; - - if (band < BAND_GAP) { - // FM band - drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), false); - BWsettemp++; - if (BWsettemp > BW_OK_BUTTON) BWsettemp = 1; - drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), true); - } else { - // AM band - drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), false); - BWsettemp++; - if (BWsettemp > BW_AM_MAX && BWsettemp < BW_OK_BUTTON) BWsettemp = BW_OK_BUTTON; - else if (BWsettemp > BW_OK_BUTTON) BWsettemp = 1; - drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), true); - } -} - -void doBWtuneDown() { - rotary = 0; - constexpr byte BW_OK_BUTTON = 20; - constexpr byte BW_AM_MAX = 4; - - if (band < BAND_GAP) { - // FM band - drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), false); - BWsettemp--; - if (BWsettemp > BW_OK_BUTTON || BWsettemp == 0) BWsettemp = BW_OK_BUTTON; - drawButton(getBWButtonLabel(BWsettemp, true), BWsettemp - 1, shouldHighlightBWButton(BWsettemp, BWset), true); - } else { - // AM band - drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), false); - BWsettemp--; - if (BWsettemp > BW_AM_MAX && BWsettemp < BW_OK_BUTTON) BWsettemp = BW_AM_MAX; - else if (BWsettemp == 0) BWsettemp = BW_OK_BUTTON; - drawButton(getBWButtonLabel(BWsettemp, false), BWsettemp - 1, (BWset == BWsettemp), true); - } -} - -void ShowStereoStatus() { - if (StereoToggle) { - if (band < BAND_GAP) Stereostatus = radio.getStereoStatus(); else Stereostatus = false; - if (Stereostatus != Stereostatusold) { - if (Stereostatus && !screenmute) tft.drawBitmap(STEREO_ICON_X, STEREO_ICON_Y, Stereo, 32, 22, StereoColor); - else if (!screenmute) tft.drawBitmap(STEREO_ICON_X, STEREO_ICON_Y, Stereo, 32, 22, GreyoutColor); - Stereostatusold = Stereostatus; +void read_encoder() { + if (!digitalRead(ROTARY_PIN_A) || !digitalRead(ROTARY_PIN_B)) { + uint32_t dt = millis() - rotarytimer; + if (dt >= 45) { + rotarycounteraccelerator = 6; + rotarycounter = 0; + } else if (dt >= 30) { + rotarycounteraccelerator = 4; + rotarycounter = 0; + } else if (dt >= 15) { + rotarycounteraccelerator = 2; + rotarycounter = 0; } } -} -void ShowRSSI() { - if (wifi) rssi = WiFi.RSSI(); else rssi = 0; - if (rssiold != rssi) { - if (!wifi && batterydetect) tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, BackgroundColor); - else if (rssi == 0) tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); - else if (rssi > -50 && rssi < 0) tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorHigh); - else if (rssi > -60) { - tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); - tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi3, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorHigh); - } else if (rssi > -70) { - tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); - tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi2, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorLow); - } else if (rssi < -70) { - tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi4, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, GreyoutColor); - tft.drawBitmap(WIFI_ICON_X, WIFI_ICON_Y, WiFi1, WIFI_ICON_WIDTH, WIFI_ICON_HEIGHT, WifiColorLow); - } - rssiold = rssi; - } -} + static uint8_t old_AB = 3; + static int8_t encval = 0; + static const int8_t enc_states[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; -void ShowBW() { - if (!BWtune && millis() >= bwupdatetimer + TIMER_BW_TIMER) bwupdatetimer = millis(); - else if(!BWtune) return; + old_AB <<= 2; + if (digitalRead(ROTARY_PIN_A)) old_AB |= 0x02; + if (digitalRead(ROTARY_PIN_B)) old_AB |= 0x01; + encval += enc_states[old_AB & 0xf]; + if (!(255 - old_AB)) encval = 0; - if (BW != BWOld || BWreset) { - if(BW == 0) panic("BW is 0"); - else if(BW > 311) panic("BW larger than 311"); - - if(BWset == 0) tftReplace(ARIGHT, String(BWOld, DEC), String(BW, DEC), 203, 4, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 28); else tftReplace(ARIGHT, String (BWOld, DEC), String(BW, DEC), 203, 4, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 28); - BWOld = BW; - BWreset = false; - if (wifi) { - Udp.beginPacket(remoteip, 9030); - Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";bandwidth=" + String(BW * 1000)); - Udp.endPacket(); - } - } -} - -void updateSWMIBand() { - switch (SWMIBandPos) { - case SW_MI_BAND_11M: - case SW_MI_BAND_13M: - case SW_MI_BAND_15M: - case SW_MI_BAND_16M: - case SW_MI_BAND_19M: - case SW_MI_BAND_22M: - case SW_MI_BAND_25M: - case SW_MI_BAND_31M: - case SW_MI_BAND_41M: - case SW_MI_BAND_49M: - case SW_MI_BAND_60M: - case SW_MI_BAND_75M: - case SW_MI_BAND_90M: - case SW_MI_BAND_120M: - case SW_MI_BAND_160M: - FrequencySprite.drawString(SWMIBandstring + " ", 0, 0, 6); - beepresetstart = true; - if (beepresetstop) { - EdgeBeeper(); - beepresetstop = false; - } - break; - - case SW_MI_BAND_GAP: - beepresetstop = true; - if (beepresetstart) { - EdgeBeeper(); - beepresetstart = false; - } - break; - } -} - -inline void updateCodetect() { - if (band > BAND_GAP) { - if (WAM) tftPrint16(ALEFT, "CO", 50, 61, PrimaryColor, PrimaryColorSmooth); - else tftPrint16(ALEFT, "CO", 50, 61, BackgroundColor, BackgroundColor); + if (encval > 3) { + if (rotarymode) rotary = -1; else rotary = 1; + rotarycounter++; + rotarytimer = millis(); + encval = 0; + } else if (encval < -3) { + if (rotarymode) rotary = 1; else rotary = -1; + rotarycounter++; + rotarytimer = millis(); + encval = 0; } } @@ -287,954 +72,6 @@ void SetTunerPatch() { } } -void ShowSignalLevel(); -void ShowOffset(); -void ShowBattery(); -void GetData() { - if (!afscreen && !rdsstatscreen) ShowSignalLevel(); - if (!BWtune && !menu && !rdsstatscreen) showPS(); - - if (band < BAND_GAP && !BWtune && !menu) { - if (advancedRDS && !afscreen && !rdsstatscreen && !screenmute) ShowAdvancedRDS(); - if (!advancedRDS && !afscreen && rdsstatscreen && !screenmute) ShowRDSStatistics(); - if (afscreen && !screenmute) ShowAFEON(); - if (!afscreen && !rdsstatscreen) { - if (!screenmute) ShowErrors(); - showPTY(); - showRadioText(); - if (millis() >= tuningtimer + 200) doAF(); - } - showPI(); - } - - ShowStereoStatus(); - - if (!screenmute) { - showCT(); - ShowRSSI(); - ShowOffset(); - ShowBW(); - updateCodetect(); - if (millis() >= tuningtimer + 200 && !wifi) ShowBattery(); - } -} - -void WakeToSleep(bool yes) { - if (yes) { - screensavertriggered = true; - switch (poweroptions) { - case LCD_OFF: - MuteScreen(1); - break; - case LCD_BRIGHTNESS_1_PERCENT: - analogWrite(CONTRASTPIN, map(ContrastSet / 100, 0, 100, 0, 255)); - break; - case LCD_BRIGHTNESS_A_QUARTER: - analogWrite(CONTRASTPIN, map(ContrastSet / 4, 0, 100, 0, 255)); - break; - case LCD_BRIGHTNESS_HALF: - analogWrite(CONTRASTPIN, map(ContrastSet / 2, 0, 100, 0, 255)); - break; - } - } else { - switch (poweroptions) { - case LCD_OFF: - MuteScreen(0); - screensavertriggered = false; - screensavertimer = millis(); - break; - case LCD_BRIGHTNESS_1_PERCENT: - case LCD_BRIGHTNESS_A_QUARTER: - case LCD_BRIGHTNESS_HALF: - MuteScreen(0); - screensavertriggered = false; - screensavertimer = millis(); - break; - } - analogWrite(CONTRASTPIN, map(ContrastSet, 0, 100, 0, 255)); - } -} - -void CheckBandForbiddenFM() { - switch (band) { - case BAND_FM: - if (bandFM == FM_BAND_OIRT) bandforbidden = 1; else bandforbidden = 0; - break; - case BAND_OIRT: - if (bandFM == FM_BAND_FM) bandforbidden = 1; else bandforbidden = 0; - break; - } -} - -void CheckBandForbiddenAM() { - switch (band) { - case BAND_LW: - if (bandAM == AM_BAND_MW_SW || bandAM == AM_BAND_MW || bandAM == AM_BAND_SW) bandforbidden = 1; - else bandforbidden = 0; - break; - case BAND_MW: - if (bandAM == AM_BAND_LW_SW || bandAM == AM_BAND_LW || bandAM == AM_BAND_SW) bandforbidden = 1; - else bandforbidden = 0; - break; - case BAND_SW: - if (bandAM == AM_BAND_LW_MW || bandAM == AM_BAND_LW || bandAM == AM_BAND_MW) bandforbidden = 1; - else bandforbidden = 0; - break; - } -} - -void FMjumptoAM() { - if (bandAM == AM_BAND_ALL || bandAM == AM_BAND_LW_MW || bandAM == AM_BAND_LW_SW || bandAM == AM_BAND_LW) { - band = BAND_LW; - if (stepsize > 3) stepsize = 3; - } else if (bandAM == AM_BAND_MW_SW || bandAM == AM_BAND_MW) band = BAND_MW; - else if (bandAM == AM_BAND_SW) band = BAND_SW; -} - -void AMjumptoFM() { - if (bandFM != FM_BAND_NONE) { - if (bandFM == FM_BAND_FM) band = BAND_FM; else band = BAND_OIRT; - } else FMjumptoAM(); -} - -void ToggleBand(byte nowBand) { - switch (nowBand) { - case BAND_LW: - if (bandAM == AM_BAND_LW_MW || bandAM == AM_BAND_ALL) band = BAND_MW; - else if (bandAM == AM_BAND_LW_SW) band = BAND_SW; - else if (bandAM == AM_BAND_LW || bandAM == AM_BAND_NONE) AMjumptoFM(); - break; - case BAND_MW: - if (bandAM == AM_BAND_MW_SW || bandAM == AM_BAND_ALL) { - band = BAND_SW; - } else if (bandAM == AM_BAND_LW_MW) { - if (bandFM != FM_BAND_NONE) { - if (bandFM == FM_BAND_FM) band = BAND_FM; else band = BAND_OIRT; - } else band = BAND_LW; - } else if (bandAM == AM_BAND_MW || bandAM == AM_BAND_NONE) AMjumptoFM(); - break; - case BAND_SW: - if (bandFM != FM_BAND_NONE) { - if (bandFM == FM_BAND_FM) band = BAND_FM; - else band = BAND_OIRT; - } else { - if (bandAM == AM_BAND_LW_SW || bandAM == AM_BAND_ALL) band = BAND_LW; - else if (bandAM == AM_BAND_MW_SW) band = BAND_MW; - else if (bandAM == AM_BAND_SW || bandAM == AM_BAND_NONE) AMjumptoFM(); - } - break; - case BAND_OIRT: - if(bandFM == FM_BAND_ALL || bandFM == FM_BAND_FM) band = BAND_FM; - else if(bandFM == FM_BAND_OIRT && bandAM != AM_BAND_NONE) FMjumptoAM(); - break; - case BAND_FM: - if (bandAM != AM_BAND_NONE) FMjumptoAM(); - else if (bandFM == FM_BAND_OIRT || bandFM == FM_BAND_ALL) band = BAND_OIRT; - break; - } -} - -void doBandSelectionFM() { - if (band > BAND_GAP) return; - - switch (bandFM) { - case FM_BAND_ALL: - break; - case FM_BAND_OIRT: - if (band == BAND_FM) { - band = BAND_OIRT; - if (frequency_OIRT > FREQ_FM_OIRT_END) { - frequency_OIRT = FREQ_FM_OIRT_START; - EdgeBeeper(); - } else if (frequency_OIRT < FREQ_FM_OIRT_START) { - frequency_OIRT = FREQ_FM_OIRT_END; - EdgeBeeper(); - } - SelectBand(); - } - break; - case FM_BAND_FM: - if (band == BAND_OIRT) { - band = BAND_FM; - if (frequency > HighEdgeSet * 10) { - frequency = LowEdgeSet * 10; - EdgeBeeper(); - } else if (frequency < LowEdgeSet * 10) { - frequency = HighEdgeSet * 10; - EdgeBeeper(); - } - SelectBand(); - } - break; - case FM_BAND_NONE: - ToggleBand(band); - SelectBand(); - break; - } -} - -void doBandSelectionAM() { - if (band < BAND_GAP) return; - - switch (bandAM) { - case AM_BAND_ALL: - break; - case AM_BAND_LW_MW: - if (band == BAND_SW) { - band = BAND_LW; - SelectBand(); - } - break; - case AM_BAND_LW_SW: - if (band == BAND_MW) { - band = BAND_LW; - SelectBand(); - } - break; - case AM_BAND_MW_SW: - if (band == BAND_LW) { - band = BAND_MW; - SelectBand(); - } - break; - case AM_BAND_LW: - if (band != BAND_LW) { - band = BAND_LW; - SelectBand(); - } - break; - case AM_BAND_MW: - if (band != BAND_MW) { - band = BAND_MW; - SelectBand(); - } - break; - case AM_BAND_SW: - if (band != BAND_SW) { - band = BAND_SW; - SelectBand(); - } - break; - case AM_BAND_NONE: - ToggleBand(band); - SelectBand(); - break; - } -} - -void BANDBUTTONPress() { - if (seek) radio.setUnMute(); - seek = false; - if (scandxmode) { - ShowFreq(5); - ShowFreq(0); - } else { - if (memorystore) { - EEPROM.writeByte(memorypos + EE_PRESETS_BAND_START, BAND_FM); - EEPROM.writeUInt((memorypos * 4) + EE_PRESETS_FREQUENCY_START, EE_PRESETS_FREQUENCY); - EEPROM.commit(); - presets[memorypos].band = BAND_FM; - presets[memorypos].frequency = EE_PRESETS_FREQUENCY; - memorystore = false; - ShowTuneMode(); - if (memoryposstatus == MEM_DARK || memoryposstatus == MEM_EXIST) { - memoryposstatus = MEM_NORMAL; - ShowMemoryPos(); - } - } else { - if (!usesquelch) radio.setUnMute(); - unsigned long counterold = millis(); - unsigned long counter = millis(); - if (!BWtune && !menu) { - while (digitalRead(BANDBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); - - if (counter - counterold < 1000) { - if (afscreen || rdsstatscreen) { - leave = true; - BuildAdvancedRDS(); - freq_in = 0; - } else if (advancedRDS) { - leave = true; - BuildDisplay(); - freq_in = 0; - SelectBand(); - screensavertimer = millis(); - } else doBandToggle(); - } else { - if (band < BAND_GAP) { - if (advancedRDS && !seek) { - BuildAFScreen(); - freq_in = 0; - } else { - BuildAdvancedRDS(); - freq_in = 0; - } - } else WakeToSleep(true); - while (digitalRead(BANDBUTTON) == LOW && counter - counterold <= 2500) counter = millis(); - if (counter - counterold > 2499) { - switch (longbandpress) { - case STANDBY: - deepSleep(); - break; - case SCREENOFF: - screensavertriggered = true; - MuteScreen(1); - break; - } - } - } - } - } - } - while (digitalRead(BANDBUTTON) == LOW) delay(DELAY_BUTTON_DEBOUNCE_MS); - delay(DELAY_BUTTON_DEBOUNCE_EXTRA_MS); -} - -void LimitAMFrequency() { - switch (band) { - case BAND_LW: - frequency_AM = frequency_LW; - if (frequency_AM > LWHighEdgeSet || frequency_AM < LWLowEdgeSet) frequency_AM = LWLowEdgeSet; - break; - case BAND_MW: - frequency_AM = frequency_MW; - if (frequency_AM > MWHighEdgeSet || frequency_AM < MWLowEdgeSet) frequency_AM = MWLowEdgeSet; - break; - case BAND_SW: - frequency_AM = frequency_SW; - if (frequency_AM > SWHighEdgeSet || frequency_AM < SWLowEdgeSet) frequency_AM = SWLowEdgeSet; - break; - } -} - -void BWButtonPress() { - if (seek) radio.setUnMute(); - seek = false; - if (afscreen || rdsstatscreen) BuildRDSStatScreen(); - else { - if (scandxmode) { - unsigned long counterold = millis(); - unsigned long counter = millis(); - while (digitalRead(BWBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); - - if (counter - counterold < 1000) { - ShowFreq(5); - ShowFreq(0); - } else cancelDXScan(); - } else { - if (!usesquelch) radio.setUnMute(); - if (!BWtune && !menu) { - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - unsigned long counterold = millis(); - unsigned long counter = millis(); - while (digitalRead(BWBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); - - if (counter - counterold < 1000) { - BuildBWSelector(); - freq_in = 0; - BWtune = true; - BWtemp = BWset; - } else { - if (band == BAND_FM || band == BAND_OIRT) doStereoToggle(); - else { - BuildBWSelector(); - freq_in = 0; - BWtune = true; - } - } - } - } - } - while (digitalRead(BWBUTTON) == LOW) delay(DELAY_BUTTON_DEBOUNCE_MS); - delay(DELAY_BUTTON_DEBOUNCE_EXTRA_MS); -} - -void doStereoToggle() { - if (StereoToggle) { - if (!screenmute) { - tft.drawBitmap(32, 5, Stereo, 32, 22, BackgroundColor); - tft.drawBitmap(38, 5, Mono, 22, 22, SecondaryColor); - } - radio.setMono(true); - StereoToggle = false; - } else { - if (!screenmute) { - tft.drawBitmap(38, 5, Mono, 22, 22, BackgroundColor); - tft.drawBitmap(32, 5, Stereo, 32, 22, GreyoutColor); - } - radio.setMono(false); - Stereostatusold = false; - StereoToggle = true; - } - radio.setAudio(audiomode); - EEPROM.writeByte(EE_BYTE_AUDIOMODE, audiomode); - EEPROM.writeByte(EE_BYTE_STEREO, StereoToggle); - EEPROM.commit(); -} - -void ShowStepSize() { - if (!advancedRDS) { - tft.fillRect(191, 38, 15, 4, GreyoutColor); - tft.fillRect(222, 38, 15, 4, GreyoutColor); - if (band < BAND_GAP) tft.fillRect(113, 38, 15, 4, GreyoutColor); else if (band != BAND_LW && band != BAND_MW) tft.fillRect(129, 38, 15, 4, GreyoutColor); - if (band < BAND_GAP) tft.fillRect(144, 38, 15, 4, GreyoutColor); else tft.fillRect(159, 38, 15, 4, GreyoutColor); - if (stepsize == 1) tft.fillRect(222, 38, 15, 4, InsignificantColor); - if (stepsize == 2) tft.fillRect(191, 38, 15, 4, InsignificantColor); - if (stepsize == 3) { - if (band < BAND_GAP) tft.fillRect(144, 38, 15, 4, InsignificantColor); else tft.fillRect(159, 38, 15, 4, InsignificantColor); - } - if (stepsize == 4) { - if (band < BAND_GAP) tft.fillRect(113, 38, 15, 4, InsignificantColor); else tft.fillRect(129, 38, 15, 4, InsignificantColor); - } - } -} - -bool IsFrequencyUsed(unsigned int freq) { - bool result = false; - for (byte x = scanstart; x <= scanstop; x++) { - if ((presets[x].band == BAND_FM || presets[x].band == BAND_OIRT) && presets[x].frequency == freq) { - result = true; - break; - } - } - return result; -} - -void ShowRDSLogo(bool RDSstatus) { - if (!screenmute) { - if (RDSstatus != RDSstatusold) { - if (RDSstatus) tft.drawBitmap(68, 5, RDSLogo, 35, 22, RDSColor); - else tft.drawBitmap(68, 5, RDSLogo, 35, 22, GreyoutColor); - } - RDSstatusold = RDSstatus; - } -} - -void showAutoSquelch(bool mode) { - if (mode) tft.drawBitmap(223, 147, AutoSQ, 18, 18, PrimaryColor); - else tft.drawBitmap(223, 147, AutoSQ, 18, 18, BackgroundColor); -} - -void updateBW() { - if (BWset == 0) { - if (!BWtune && !screenmute && !advancedRDS && !afscreen && !rdsstatscreen) { - tft.fillRoundRect(248, 36, 69, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "AUTO BW", 282, 38, BackgroundColor, SecondaryColor); - } - radio.setFMABandw(); - } else { - if (!BWtune && !screenmute && !advancedRDS && !afscreen && !rdsstatscreen) { - tft.fillRoundRect(248, 36, 69, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "AUTO BW", 282, 38, BackgroundColor, GreyoutColor); - } - } -} - -void updateiMS() { - if (band < BAND_GAP) { - if (iMSset == 0) { - if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { - tft.fillRoundRect(249, 57, 30, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "iMS", 265, 59, BackgroundColor, SecondaryColor); - } - radio.setiMS(1); - } else { - if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { - tft.fillRoundRect(249, 57, 30, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "iMS", 265, 59, BackgroundColor, GreyoutColor); - } - radio.setiMS(0); - } - } -} - -void updateEQ() { - if (band < BAND_GAP) { - if (EQset == 0) { - if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { - tft.fillRoundRect(287, 57, 30, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "EQ", 301, 59, BackgroundColor, SecondaryColor); - } - radio.setEQ(1); - } else { - if (!screenmute && !advancedRDS && !afscreen && !rdsstatscreen && !BWtune) { - tft.fillRoundRect(287, 57, 30, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "EQ", 301, 59, BackgroundColor, GreyoutColor); - } - radio.setEQ(0); - } - } -} - -void DataPrint(String string) { - if (XDRGTKUSB) Serial.print(string); - if (XDRGTKTCP) RemoteClient.print(string); -} - -void toggleiMSEQ() { - if (band < BAND_GAP) { - if (iMSEQ == 0) iMSEQ = 1; - - if (iMSEQ == 4) { - iMSset = 0; - EQset = 0; - updateiMS(); - updateEQ(); - iMSEQ = 0; - } else if (iMSEQ == 3) { - iMSset = 1; - EQset = 0; - updateiMS(); - updateEQ(); - iMSEQ = 4; - } else if (iMSEQ == 2) { - iMSset = 0; - EQset = 1; - updateiMS(); - updateEQ(); - iMSEQ = 3; - } else if (iMSEQ == 1) { - iMSset = 1; - EQset = 1; - updateiMS(); - updateEQ(); - iMSEQ = 2; - } - EEPROM.writeByte(EE_BYTE_IMSSET, iMSset); - EEPROM.writeByte(EE_BYTE_EQSET, EQset); - EEPROM.commit(); - if (XDRGTKUSB || XDRGTKTCP) DataPrint("G" + String(!EQset) + String(!iMSset) + "\n"); - } -} - -void TuneFreq(int temp) { - int newfreq = temp; - - if (band == BAND_FM) { - while (newfreq < (LowEdgeSet * 10)) newfreq *= 10; - if (newfreq > (HighEdgeSet * 10)) { - EdgeBeeper(); - return; - } - if (newfreq == frequency) return; - frequency = newfreq; - radio.SetFreq(frequency); - - } else if (band == BAND_OIRT) { - while (newfreq < (LowEdgeOIRTSet * 10)) newfreq *= 10; - if (newfreq > HighEdgeOIRTSet) { - EdgeBeeper(); - return; - } - if (newfreq == frequency_OIRT) return; - frequency_OIRT = newfreq; - radio.SetFreq(frequency_OIRT); - - } else if (band == BAND_LW) { - while (newfreq < LWLowEdgeSet) newfreq *= 10; - if (newfreq > LWHighEdgeSet) { - EdgeBeeper(); - return; - } - if (newfreq == frequency_LW) return; - frequency_AM = newfreq; - frequency_LW = newfreq; - radio.SetFreqAM(frequency_AM); - - } else if (band == BAND_MW) { - while (newfreq < MWLowEdgeSet) newfreq *= 10; - if (newfreq > MWHighEdgeSet) { - EdgeBeeper(); - return; - } - if (newfreq == frequency_MW) return; - frequency_AM = newfreq; - frequency_MW = newfreq; - radio.SetFreqAM(frequency_AM); - - } else if (band == BAND_SW) { - while (newfreq < SWLowEdgeSet) newfreq *= 10; - if (newfreq > SWHighEdgeSet) { - EdgeBeeper(); - return; - } - if (newfreq == frequency_SW) return; - frequency_AM = newfreq; - frequency_SW = newfreq; - radio.SetFreqAM(frequency_AM); - } - - aftest = true; - aftimer = millis(); - - radio.clearRDS(); - if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); - if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); -} - -void ShowNum(int val) { - FrequencySprite.setTextDatum(TR_DATUM); - - FrequencySprite.fillSprite(BackgroundColor); - FrequencySprite.setTextColor(SecondaryColor, SecondaryColorSmooth, false); - FrequencySprite.drawString(String(val) + " ", 218, -6, freqfont); - FrequencySprite.pushSprite(46, 46); -} - -byte numval[16] = {2, 3, 127, 5, 6, 0, 9, 13, 8, 7, 4, 1, 0, 0, 0, 0}; -int GetNum() { - if(!gpio_chip) return -1; - // Get input port 0 and 1 - Wire.beginTransmission(XL9555_ADDRESS); - Wire.write(0x00); - Wire.endTransmission(); - Wire.requestFrom(XL9555_ADDRESS, 2); - - // According to the schematic of the DP666, this is the table that the buttons are connected to: - // IO0_0 = NUM2 - // IO0_1 = NUM3 - // IO0_2 = BACKSPACE (DX is printed on the case) - // IO0_3 = NUM5 - // IO0_4 = NUM6 - // IO0_5 = NUM0 - // IO0_6 = NUM9 - // IO0_7 = ENTER - // IO1_0 = NUM8 - // IO1_1 = NUM7 - // IO1_2 = NUM4 - // IO1_3 = NUM1 - // Rest is NC - // According to the docs, register 0 contains pins IO0_x where x is equal to the bit from the right (x = 7, is MSB) - - int cnt = 0; - uint16_t temp; - unsigned int num; - if(Wire.available() == 2) { - keypadtimer = millis(); - - temp = Wire.read() & 0xFF; - temp |= (Wire.read() & 0xFF) << 8; - for (int i = 0; i < 16; i++) { - if ((temp & 0x01) == 0) { - num = numval[i]; - cnt++; - } - temp >>= 1; - } - if (cnt == 1) return num; - } - - return -1; -} - -void StoreMemoryPos(uint8_t _pos) { - EEPROM.writeByte(_pos + EE_PRESETS_BAND_START, band); - EEPROM.writeByte(_pos + EE_PRESET_BW_START, BWset); - EEPROM.writeByte(_pos + EE_PRESET_MS_START, StereoToggle); - - if (band == BAND_FM) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency); - else if (band == BAND_OIRT) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_OIRT); - else if (band == BAND_LW) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_LW); - else if (band == BAND_MW) EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_MW); - else EEPROM.writeUInt((_pos * 4) + EE_PRESETS_FREQUENCY_START, frequency_SW); - - presets[_pos].band = band; - presets[_pos].bw = BWset; - presets[_pos].ms = StereoToggle; - - String stationName = radio.rds.stationName; - char stationNameCharArray[10]; - char picodeArray[7]; - stationName.toCharArray(stationNameCharArray, sizeof(stationNameCharArray)); - memcpy(picodeArray, radio.rds.picode, sizeof(picodeArray)); - - for (int y = 0; y < 9; y++) { - presets[_pos].RDSPS[y] = (y < strlen(stationNameCharArray)) ? stationNameCharArray[y] : '\0'; - EEPROM.writeByte((_pos * 9) + y + EE_PRESETS_RDSPS_START, presets[_pos].RDSPS[y]); - } - - for (int y = 0; y < 5; y++) { - presets[_pos].RDSPI[y] = (y < sizeof(picodeArray)) ? picodeArray[y] : '\0'; - EEPROM.writeByte((_pos * 5) + y + EE_PRESETS_RDSPI_START, presets[_pos].RDSPI[y]); - } - - EEPROM.commit(); - - if (band == BAND_FM) presets[_pos].frequency = frequency; - else if (band == BAND_OIRT) presets[_pos].frequency = frequency_OIRT; - else if (band == BAND_LW) presets[_pos].frequency = frequency_LW; - else if (band == BAND_MW) presets[_pos].frequency = frequency_MW; - else presets[_pos].frequency = frequency_SW; -} - -void startFMDXScan() { - screensavertimer = millis(); - initdxscan = true; - scanholdflag = false; - autologged = false; - - if (menu) endMenu(); - if (afscreen || advancedRDS || rdsstatscreen) { - BuildDisplay(); - freq_in = 0; - } - - memoryposold = memorypos; - if (memorypos > scanstop || memorypos < scanstart) memorypos = scanstart; - scanmodeold = tunemode; - - if (scanmem) { - tunemode = TUNE_MEM; - if (band != presets[memorypos].band) { - band = presets[memorypos].band; - SelectBand(); - } - DoMemoryPosTune(); - } else { - tunemode = TUNE_MAN; - if (band != presets[memorypos].band) { - band = presets[memorypos].band; - SelectBand(); - } - TuneUp(); - ShowFreq(0); - } - if (scanmute) { - radio.setMute(); - tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - SQ = true; - Squelchold = -2; - } - scantimer = millis(); - scandxmode = true; - ShowTuneMode(); - if (XDRGTKUSB || XDRGTKTCP) DataPrint("J1\n"); -} - -void doBandToggle() { - if (tunemode != TUNE_MEM) { - ToggleBand(band); - radio.clearRDS(); - StoreFrequency(); - SelectBand(); - if (XDRGTKUSB || XDRGTKTCP) { - if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); - else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); - else DataPrint("M1\nT" + String(frequency_AM) + "\n"); - } - } else { - scanmodeold = tunemode; - startFMDXScan(); - return; - } - screensavertimer = millis(); -} - -void NumpadProcess(int num) { - if (scandxmode) { - if (num == 127) { - ShowFreq(5); - ShowFreq(0); - } - } else if (tunemode == TUNE_MEM) { - if (num == 127) { - freq_in = 0; - menuoption = ITEM1; - menupage = DXMODE; - menuitem = 0; - submenu = true; - menu = true; - if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); - BuildMenu(); - } else if (num == 13) { - if (freq_in > 0 && freq_in <= EE_PRESETS_CNT) { - byte oldmemorypos = memorypos; - memorypos = freq_in - 1; - if (IsStationEmpty()) { - // Flash red and revert - FrequencySprite.setTextDatum(TR_DATUM); - FrequencySprite.fillSprite(BackgroundColor); - FrequencySprite.setTextColor(SignificantColor, SignificantColorSmooth, false); - FrequencySprite.drawString(String(freq_in) + " ", 218, -6); - FrequencySprite.pushSprite(46, 46); - delay(500); - memorypos = oldmemorypos; - ShowFreq(0); - ShowMemoryPos(); - } else { - DoMemoryPosTune(); - ShowMemoryPos(); - } - } else ShowFreq(0); - freq_in = 0; - } else { - if (freq_in / 100 == 0) { - int temp = freq_in * 10 + num; - if (temp <= EE_PRESETS_CNT) freq_in = temp; - } - ShowNum(freq_in); - } - } else { - if (num == 127) { - freq_in = 0; - menuoption = ITEM1; - menupage = DXMODE; - menuitem = 0; - submenu = true; - menu = true; - if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); - BuildMenu(); - } else if (num == 13) { - if (freq_in != 0) { - TuneFreq(freq_in); - if (XDRGTKUSB || XDRGTKTCP) { - if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); - } - if (!memorystore) { - if (!memtune) radio.clearRDS(); - memtune = false; - ShowFreq(0); - store = true; - } - } else ShowFreq(0); - freq_in = 0; - } else { - if (freq_in / 10000 == 0) freq_in = freq_in * 10 + num; - ShowNum(freq_in); - } - } -} - -void setAutoSpeedSPI() { - switch (frequency / 10) { - case 875 ... 877: tft.setSPISpeed(28); break; - case 878 ... 881: tft.setSPISpeed(24); break; - case 882 ... 892: tft.setSPISpeed(42); break; - case 893 ... 899: tft.setSPISpeed(31); break; - case 900 ... 904: tft.setSPISpeed(12); break; - case 905 ... 906: tft.setSPISpeed(16); break; - case 907 ... 910: tft.setSPISpeed(11); break; - case 911 ... 916: tft.setSPISpeed(15); break; - case 917 ... 921: tft.setSPISpeed(24); break; - case 922 ... 928: tft.setSPISpeed(13); break; - case 929: tft.setSPISpeed(11); break; - case 930 ... 932: tft.setSPISpeed(13); break; - case 933 ... 939: tft.setSPISpeed(18); break; - case 940 ... 941: tft.setSPISpeed(12); break; - case 942: tft.setSPISpeed(17); break; - case 943 ... 949: tft.setSPISpeed(15); break; - case 950: tft.setSPISpeed(19); break; - case 951: tft.setSPISpeed(15); break; - case 952 ... 960: tft.setSPISpeed(22); break; - case 961 ... 965: tft.setSPISpeed(15); break; - case 966 ... 973: tft.setSPISpeed(22); break; - case 974 ... 979: tft.setSPISpeed(17); break; - case 980 ... 982: tft.setSPISpeed(20); break; - case 983 ... 987: tft.setSPISpeed(18); break; - case 988 ... 993: tft.setSPISpeed(11); break; - case 994 ... 996: tft.setSPISpeed(18); break; - case 997 ... 1005: tft.setSPISpeed(11); break; - case 1006: tft.setSPISpeed(13); break; - case 1007 ... 1011: tft.setSPISpeed(11); break; - case 1012 ... 1016: tft.setSPISpeed(18); break; - case 1017 ... 1026: tft.setSPISpeed(13); break; - case 1027 ... 1035: tft.setSPISpeed(23); break; - case 1036 ... 1038: tft.setSPISpeed(15); break; - case 1039 ... 1042: tft.setSPISpeed(12); break; - case 1043 ... 1047: tft.setSPISpeed(23); break; - case 1048 ... 1050: tft.setSPISpeed(28); break; - case 1051 ... 1062: tft.setSPISpeed(15); break; - case 1063 ... 1068: tft.setSPISpeed(18); break; - case 1069 ... 1074: tft.setSPISpeed(14); break; - case 1075: tft.setSPISpeed(17); break; - case 1076 ... 1080: tft.setSPISpeed(15); break; - default: tft.setSPISpeed(35); break; - } -} - -void endMenu() { - if(rds_settings_changed) { - radio.clearRDS(); - RDSstatus = false; - } - rds_settings_changed = menu = false; - menuopen = false; - LowLevelInit = true; - submenu = false; - menuoption = ITEM1; - menupage = INDEX; - menuitem = 0; - saveData(); - if (af == 2) radio.rds.afreg = true; else radio.rds.afreg = false; - Serial.end(); - if (wifi) remoteip = IPAddress(WiFi.localIP()[0], WiFi.localIP()[1], WiFi.localIP()[2], subnetclient); - if (USBmode) Serial.updateBaudRate(19200); else Serial.updateBaudRate(115200); - - leave = true; - if (language == LANGUAGE_CHS) PSSprite.setTextFont(3); else PSSprite.setTextFont(2); - PSSprite.setTextDatum(TL_DATUM); - BuildDisplay(); - SelectBand(); -} - -void cancelDXScan() { - tunemode = scanmodeold; - memorypos = memoryposold; - scandxmode = false; - if (scanmute) { - radio.setUnMute(); - tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - - if (!flashing) { - tft.fillRoundRect(2, 80, 40, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SecondaryColor); - } - - SQ = false; - Squelchold = -2; - } - - ShowTuneMode(); - ShowMemoryPos(); - if (XDRGTKUSB || XDRGTKTCP) DataPrint("J0\n"); -} - -void MuteScreen(bool setting) { - if (!setting && screenmute) { - screenmute = false; - setupmode = true; - leave = true; - tft.writecommand(0x11); - analogWrite(CONTRASTPIN, map(ContrastSet, 0, 100, 0, 255)); - if (band < BAND_GAP) { - if (afscreen) { - BuildAFScreen(); - freq_in = 0; - } else if (advancedRDS) { - BuildAdvancedRDS(); - freq_in = 0; - } else if (rdsstatscreen) { - BuildRDSStatScreen(); - freq_in = 0; - } else { - BuildDisplay(); - freq_in = 0; - SelectBand(); - } - } else { - BuildDisplay(); - freq_in = 0; - SelectBand(); - } - setupmode = false; - } else if (setting && !screenmute) { - screenmute = true; - analogWrite(CONTRASTPIN, 0); - tft.writecommand(0x10); - } -} -#pragma endregion - void setup_periph() { Wire.setClock(400000); Serial.println(); @@ -1341,17 +178,16 @@ void later_setup_periph() { else console.print("Battery detected"); } -void read_encoder(); void setup() { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); - gpio_set_drive_capability((gpio_num_t) 5, GPIO_DRIVE_CAP_0); - gpio_set_drive_capability((gpio_num_t) 16, GPIO_DRIVE_CAP_0); - gpio_set_drive_capability((gpio_num_t) 17, GPIO_DRIVE_CAP_0); - gpio_set_drive_capability((gpio_num_t) 18, GPIO_DRIVE_CAP_0); - gpio_set_drive_capability((gpio_num_t) 19, GPIO_DRIVE_CAP_0); - gpio_set_drive_capability((gpio_num_t) 21, GPIO_DRIVE_CAP_0); - gpio_set_drive_capability((gpio_num_t) 22, GPIO_DRIVE_CAP_0); - gpio_set_drive_capability((gpio_num_t) 23, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)5, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)16, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)17, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)18, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)19, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)21, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)22, GPIO_DRIVE_CAP_0); + gpio_set_drive_capability((gpio_num_t)23, GPIO_DRIVE_CAP_0); analogWriteFrequency(5000); @@ -1612,2473 +448,4 @@ void setup() { screensavertimer = millis(); tottimer = millis(); console.reset(); -} - -void ShowAudioLevel(); -void doSquelch(); - -void handleWiFi() { - if (wifi && !menu) { - webserver.handleClient(); - - if (millis() >= udplogtimer + UDP_LOG_INTERVAL_MS) { - sendUDPlog(); - udplogtimer = millis(); - } - - if (millis() >= NTPtimer + NTP_UPDATE_INTERVAL_MS) { - NTPupdate(); - NTPtimer = millis(); - } - } -} - -void handleTouch() { - if (hardwaremodel == PORTABLE_TOUCH_ILI9341 && touch_detect) { - if (tft.getTouchRawZ() > TOUCH_RAW_Z_THRESHOLD) { - uint16_t x, y; - tft.getTouch(&x, &y); - if (x > 0 || y > 0) { - if (!firstTouchHandled) { - doTouchEvent(x, y); - firstTouchHandled = true; - lastTouchTime = millis(); - } else if (touchrepeat && millis() - lastTouchTime >= DELAY_TOUCH_REPEAT_MS) { - doTouchEvent(x, y); - } - } - } else { - firstTouchHandled = false; - touch_detect = false; - } - } -} - -void handleTimers() { - // tottimer is like the time of the last interaction - if (tot != 0 && millis() >= tottimer + (tot * TOT_MULTIPLIER_MS)) { - deepSleep(); - } - - if (freq_in != 0 && millis() >= keypadtimer + DELAY_KEYPAD_TIMEOUT_MS) { - freq_in = 0; - ShowFreq(0); - if (tunemode == TUNE_MEM) ShowMemoryPos(); - } -} - -void loop() { - if(i2c_pc_control) { - total_pc_control(); - if(i2c_pc_control) return; - } - - handleWiFi(); - handleTouch(); - Communication(); - handleTimers(); - - if (scandxmode) { - unsigned long waitTime = (scanhold == 0) ? SCAN_HOLD_DEFAULT_MS : (scanhold * 1000); - if (!scanholdflag) scanholdflag = isSignalQualityGood(USN, WAM, OStatus); - bool bypassMillisCheck = scanholdonsignal && !scanholdflag; - bool shouldScan = bypassMillisCheck || (!bypassMillisCheck && (millis() >= scantimer + waitTime)); - - if (shouldScan) { - if (scanmute && scanholdonsignal) { - radio.setMute(); - if (!screenmute) tft.drawBitmap(SPEAKER_ICON_X, SPEAKER_ICON_Y, Speaker, SPEAKER_ICON_WIDTH, SPEAKER_ICON_HEIGHT, PrimaryColor); - SQ = true; - } - scanholdflag = false; - if (scanmem) { - memorypos++; - if (memorypos > scanstop) memorypos = scanstart; - while (IsStationEmpty() || (presets[memorypos].band != BAND_FM && presets[memorypos].band != BAND_OIRT)) { - memorypos++; - if (memorypos > scanstop) { - memorypos = scanstart; - break; - } - } - doLog(); - DoMemoryPosTune(); - radio.clearRDS(); - autologged = false; - ShowMemoryPos(); - } else { - doLog(); - TuneUp(); - autologged = false; - ShowFreq(0); - if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); - } - scantimer = millis(); - initdxscan = false; - } else { - if (scanmute && scanholdonsignal) { - radio.setUnMute(); - SQ = false; - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - } - } - - if (millis() >= flashingtimer + 500) { - flashing = !flashing; - if (flashing) { - tft.fillRoundRect(2, 80, 40, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SecondaryColor); - } else { - tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); - } - flashingtimer = millis(); - } - - if (!scanholdflag) delay(75); - radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - - if (!initdxscan) { - switch (scancancel) { - case CORRECTPI: - if (RDSstatus && radio.rds.correctPI != 0) cancelDXScan(); - break; - case SIGNAL: - if (isSignalQualityGood(USN, WAM, OStatus) && (Squelch < SStatus || Squelch == SQUELCH_MAX_VALUE)) cancelDXScan(); - break; - } - } - } - - if (millis() >= tuningtimer + 200) rdsflagreset = false; - - if (millis() >= tuningtimer + 2000) { - if (store) { - StoreFrequency(); - store = false; - } - } - - if (!BWtune && !menu && !afscreen && !rdsstatscreen && !scandxmode) { - if (af != 0 && dropout && millis() >= aftimer + 1000) { - aftimer = millis(); - if (radio.af_counter == 0) { - if (findMemoryAF && radio.rds.correctPI != 0 && tunemode == TUNE_MEM && (USN > 250 || WAM > 250)) { - radio.setMute(); - tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - SQ = true; - if (!screenmute) { - if (advancedRDS) { - tft.drawRoundRect(10, 30, 300, 170, 2, ActiveColor); - tft.fillRoundRect(12, 32, 296, 166, 2, BackgroundColor); - tftPrint(ACENTER, textUI(31), 160, 100, ActiveColor, ActiveColorSmooth, 28); - } else ShowFreq(1); - } - - bool foundmemaf = false; - for (int x = 8750; x <= 10800; x += 10) { - if (rotary != 0 || digitalRead(BANDBUTTON) == LOW || digitalRead(MODEBUTTON) == LOW || digitalRead(BWBUTTON) == LOW || digitalRead(ROTARY_BUTTON) == LOW) break; - radio.SetFreq(x); - unsigned long millisold = millis(); - while (millis() - millisold < 187) { - if (!screenmute && !advancedRDS) ShowAudioLevel(); - } - if (radio.rds.correctPI == radio.getBlockA()) { - frequency = x; - foundmemaf = true; - break; - } - } - - if (!foundmemaf) { - frequency = freqold; - radio.SetFreq(frequency); - } - - if (!screenmute) { - if (advancedRDS) { - leave = true; - BuildAdvancedRDS(); - freq_in = 0; - } else ShowFreq(0); - } - - radio.setUnMute(); - SQ = false; - tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - } - findMemoryAF = false; - } else frequency = radio.TestAF(); - if (freqold != frequency) { - ShowFreq(0); - dropout = true; - if (radio.afmethodB) { - afmethodBold = true; - radio.clearRDS(); - } - } - if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); - if (screenmute) { - freqold = frequency; - dropout = false; - } - store = true; - } - - if (band == BAND_FM && af != 0 && radio.rds.correctPI != 0) { - if ((aftest && millis() >= aftimer + 3000) || ((USN > 250 || WAM > 250) && millis() >= aftimer + 1000)) { - aftimer = millis(); - aftest = false; - frequency = radio.TestAF(); - if (freqold != frequency) { - ShowFreq(0); - dropout = true; - if (radio.afmethodB) { - afmethodBold = true; - radio.clearRDS(); - } - if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); - if (screenmute) { - freqold = frequency; - dropout = false; - } - store = true; - } - } - - if (band == BAND_FM && millis() >= aftimer + 10000) { - aftimer = millis(); - if (USN > 150 || WAM > 150) { - frequency = radio.TestAF(); - if (freqold != frequency) { - ShowFreq(0); - dropout = true; - if (radio.afmethodB) { - afmethodBold = true; - radio.clearRDS(); - } - if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); - store = true; - if (screenmute) { - freqold = frequency; - dropout = false; - } - } - } - } - } - } - - if (seek) Seek(direction); - - if ((SStatus / 10 > LowLevelSet) && !LowLevelInit && !BWtune && !menu && band < BAND_GAP) { - if (!screenmute && !advancedRDS && !rdsstatscreen && !afscreen) { - if (showaudio) { - tftPrint16(ALEFT, "10", 24, 144, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "30", 54, 144, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "50", 84, 144, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "70", 114, 144, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "100", 160, 144, ActiveColor, ActiveColorSmooth); - tftPrint16(ACENTER, "A", 7, 128, ActiveColor, ActiveColorSmooth); - for (byte segments = 0; segments < 93; segments++) { - if (segments > 54) { - if (((segments - 53) % 10) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, BarSignificantColor); - } else { - if (((segments + 1) % 6) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, BarInsignificantColor); - } - } - } - if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, ActiveColor, ActiveColorSmooth); - else { - tftPrint16(ALEFT, "PI", 212, 184, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "ID", 212, 201, ActiveColor, ActiveColorSmooth); - } - tftPrint16(ALEFT, "PS", 3, 193, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "RT", 3, 221, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "PTY", 3, 163, ActiveColor, ActiveColorSmooth); - if (!showaudio) tft.drawLine(16, 143, 189, 143, GreyoutColor); else tft.drawLine(16, 143, 189, 143, ActiveColor); - } - LowLevelInit = true; - } - - if ((SStatus / 10 <= LowLevelSet) && band < BAND_GAP) { - if (LowLevelInit && !BWtune && !menu) { - if (!screenmute && !rdsstatscreen && !afscreen && !advancedRDS) { - if(showaudio) { - tftPrint16(ALEFT, "10", 24, 144, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "30", 54, 144, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "50", 84, 144, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "70", 114, 144, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "100", 160, 144, GreyoutColor, BackgroundColor); - tftPrint16(ACENTER, "A", 7, 128, GreyoutColor, BackgroundColor); - tft.fillRect(16, 133, 174, 6, GreyoutColor); - for (byte segments = 0; segments < 93; segments++) { - if (segments > 54) { - if (((segments - 53) % 10) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, GreyoutColor); - } else { - if (((segments + 1) % 6) == 0) tft.fillRect(22 + (2 * segments), 141, 2, 2, GreyoutColor); - } - } - } - if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, GreyoutColor, BackgroundColor); - else { - tftPrint16(ALEFT, "PI", 212, 184, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "ID", 212, 201, GreyoutColor, BackgroundColor); - } - tftPrint16(ALEFT, "PS", 3, 193, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "RT", 3, 221, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "PTY", 3, 163, GreyoutColor, BackgroundColor); - tft.drawLine(16, 143, 189, 143, GreyoutColor); - tft.drawBitmap(68, 5, RDSLogo, 35, 22, GreyoutColor); - } - LowLevelInit = false; - } - - if (!BWtune && !menu && (screenmute || radio.rds.correctPI != 0)) readRds(); - if (millis() >= lowsignaltimer + 300) { - lowsignaltimer = millis(); - if (af || (!screenmute || (screenmute && (XDRGTKTCP || XDRGTKUSB)))) { - if (band < BAND_GAP) radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - else radio.getStatusAM(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - } - if (!BWtune && !menu) { - doSquelch(); - GetData(); - } - } - - } else { - if (af || (!screenmute || (screenmute && (XDRGTKTCP || XDRGTKUSB)))) { - if (band < BAND_GAP) radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - else radio.getStatusAM(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - } - if (!BWtune && !menu) { - doSquelch(); - if (millis() >= tuningtimer + 200) readRds(); - GetData(); - if (!screenmute && !rdsstatscreen && !afscreen && !advancedRDS) ShowAudioLevel(); - } - } - - if (rotary == -1) { - tottimer = millis(); - if (screensavertriggered) { - if (!touchrotating) { - rotary = 0; - WakeToSleep(REVERSE); - } else { - if (BWtune) doBWtuneUp(); else KeyUp(); - } - } else { - if (BWtune) doBWtuneUp(); else KeyUp(); - if (rotaryaccelerate && rotarycounter > 2 && !BWtune && !menu) { - for (int i = 0; i < rotarycounteraccelerator; i++) KeyUp(); - rotarycounter = 0; - } - if (screensaverset > 0 && !BWtune && !menu && !screensavertriggered) screensavertimer = millis(); - } - } - - if (rotary == 1) { - tottimer = millis(); - if (screensavertriggered) { - if (!touchrotating) { - rotary = 0; - WakeToSleep(REVERSE); - } else { - if (BWtune) doBWtuneDown(); else KeyDown(); - } - } else { - if (BWtune) doBWtuneDown(); else KeyDown(); - if (rotaryaccelerate && rotarycounter > 2 && !BWtune && !menu) { - for (int i = 0; i < rotarycounteraccelerator; i++) KeyDown(); - rotarycounter = 0; - } - if (screensaverset > 0 && !BWtune && !menu && !screensavertriggered) screensavertimer = millis(); - } - } - - if (digitalRead(BANDBUTTON) == LOW) { - tottimer = millis(); - if (screensavertriggered) { - WakeToSleep(REVERSE); - while (digitalRead(BANDBUTTON) == LOW); - } else BANDBUTTONPress(); - } - - if (digitalRead(ROTARY_BUTTON) == LOW) { - tottimer = millis(); - if (screensavertriggered) { - WakeToSleep(REVERSE); - while (digitalRead(ROTARY_BUTTON) == LOW); - } else if (!afscreen && !rdsstatscreen) ButtonPress(); - } - - if (digitalRead(MODEBUTTON) == LOW) { - tottimer = millis(); - if (screensavertriggered) { - WakeToSleep(REVERSE); - while (digitalRead(MODEBUTTON) == LOW); - } else if(!screenmute) ModeButtonPress(); - } - - if (digitalRead(BWBUTTON) == LOW && !BWtune) { - tottimer = millis(); - if (screensavertriggered) { - WakeToSleep(REVERSE); - while (digitalRead(BWBUTTON) == LOW); - } else if(!screenmute) BWButtonPress(); - } - - if (digitalRead(EXT_IRQ) == LOW) { - if (screensavertriggered) WakeToSleep(REVERSE); - int num = GetNum(); - if (!screenmute && !BWtune && !menu && !advancedRDS && !rdsstatscreen && !afscreen && num != -1) NumpadProcess(num); - } - - if (screensaverset > 0 && !screensavertriggered && !BWtune && !menu && millis() >= screensavertimer + 1000 * screensaverOptions[screensaverset]) WakeToSleep(true); -} - -void DivdeSWMIBand() { - if (frequency_AM >= FREQ_SW_160M_START && frequency_AM <= FREQ_SW_160M_END) { - SWMIBandPos = SW_MI_BAND_160M; - frequency_MIBand_160M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_120M_START && frequency_AM <= FREQ_SW_120M_END) { - SWMIBandPos = SW_MI_BAND_120M; - frequency_MIBand_120M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_90M_START && frequency_AM <= FREQ_SW_90M_END) { - SWMIBandPos = SW_MI_BAND_90M; - frequency_MIBand_90M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_75M_START && frequency_AM <= FREQ_SW_75M_END) { - SWMIBandPos = SW_MI_BAND_75M; - frequency_MIBand_75M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_60M_START && frequency_AM <= FREQ_SW_60M_END) { - SWMIBandPos = SW_MI_BAND_60M; - frequency_MIBand_60M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_49M_START && frequency_AM <= FREQ_SW_49M_END) { - SWMIBandPos = SW_MI_BAND_49M; - frequency_MIBand_49M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_41M_START && frequency_AM <= FREQ_SW_41M_END) { - SWMIBandPos = SW_MI_BAND_41M; - frequency_MIBand_41M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_31M_START && frequency_AM <= FREQ_SW_31M_END) { - SWMIBandPos = SW_MI_BAND_31M; - frequency_MIBand_31M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_25M_START && frequency_AM <= FREQ_SW_25M_END) { - SWMIBandPos = SW_MI_BAND_25M; - frequency_MIBand_25M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_22M_START && frequency_AM <= FREQ_SW_22M_END) { - SWMIBandPos = SW_MI_BAND_22M; - frequency_MIBand_22M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_19M_START && frequency_AM <= FREQ_SW_19M_END) { - SWMIBandPos = SW_MI_BAND_19M; - frequency_MIBand_19M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_16M_START && frequency_AM <= FREQ_SW_16M_END) { - SWMIBandPos = SW_MI_BAND_16M; - frequency_MIBand_16M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_15M_START && frequency_AM <= FREQ_SW_15M_END) { - SWMIBandPos = SW_MI_BAND_15M; - frequency_MIBand_15M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_13M_START && frequency_AM <= FREQ_SW_13M_END) { - SWMIBandPos = SW_MI_BAND_13M; - frequency_MIBand_13M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else if (frequency_AM >= FREQ_SW_11M_START && frequency_AM <= FREQ_SW_11M_END) { - SWMIBandPos = SW_MI_BAND_11M; - frequency_MIBand_11M = frequency_AM; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - } else { - if (SWMIBandPos > SW_MI_BAND_GAP) { - SWMIBandPosold = SWMIBandPos; - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - } - SWMIBandPos = SW_MI_BAND_GAP; - } -} - -void ToggleSWMIBand(bool frequencyup) { - switch (SWMIBandPosold) { - case SW_MI_BAND_GAP: - if (frequencyup) { - SWMIBandPos = SW_MI_BAND_160M; - SWMIBandPosold = SWMIBandPos; - frequency_AM = FREQ_SW_160M_START; - } else { - SWMIBandPos = SW_MI_BAND_11M; - SWMIBandPosold = SWMIBandPos; - frequency_AM = FREQ_SW_11M_END; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_11M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_160M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_160M == 0 ? FREQ_SW_160M_START : frequency_MIBand_160M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_13M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_13M == 0 ? FREQ_SW_13M_END : frequency_MIBand_13M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_13M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_11M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_11M == 0 ? FREQ_SW_11M_START : frequency_MIBand_11M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_15M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_15M == 0 ? FREQ_SW_15M_END : frequency_MIBand_15M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_15M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_13M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_13M == 0 ? FREQ_SW_13M_START : frequency_MIBand_13M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_16M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_16M == 0 ? FREQ_SW_16M_END : frequency_MIBand_16M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_16M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_15M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_15M == 0 ? FREQ_SW_15M_START : frequency_MIBand_15M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_19M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_19M == 0 ? FREQ_SW_19M_END : frequency_MIBand_19M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_19M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_16M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_16M == 0 ? FREQ_SW_16M_START : frequency_MIBand_16M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_22M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_22M == 0 ? FREQ_SW_22M_END : frequency_MIBand_22M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_22M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_19M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_19M == 0 ? FREQ_SW_19M_START : frequency_MIBand_19M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_25M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_25M == 0 ? FREQ_SW_25M_END : frequency_MIBand_25M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_25M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_22M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_22M == 0 ? FREQ_SW_22M_START : frequency_MIBand_22M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_31M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_31M == 0 ? FREQ_SW_31M_END : frequency_MIBand_31M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_31M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_25M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_25M == 0 ? FREQ_SW_25M_START : frequency_MIBand_25M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_41M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_41M == 0 ? FREQ_SW_41M_END : frequency_MIBand_41M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_41M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_31M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_31M == 0 ? FREQ_SW_31M_START : frequency_MIBand_31M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_49M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_49M == 0 ? FREQ_SW_49M_END : frequency_MIBand_49M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_49M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_41M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_41M == 0 ? FREQ_SW_41M_START : frequency_MIBand_41M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_60M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_60M == 0 ? FREQ_SW_60M_END : frequency_MIBand_60M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_60M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_49M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_49M == 0 ? FREQ_SW_49M_START : frequency_MIBand_49M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_75M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_75M == 0 ? FREQ_SW_75M_END : frequency_MIBand_75M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_75M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_60M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_60M == 0 ? FREQ_SW_60M_START : frequency_MIBand_60M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_90M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_90M == 0 ? FREQ_SW_90M_END : frequency_MIBand_90M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_90M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_75M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_75M == 0 ? FREQ_SW_75M_START : frequency_MIBand_75M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_120M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_120M == 0 ? FREQ_SW_120M_END : frequency_MIBand_120M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_120M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_90M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_90M == 0 ? FREQ_SW_90M_START : frequency_MIBand_90M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_160M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_160M == 0 ? FREQ_SW_160M_END : frequency_MIBand_160M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - case SW_MI_BAND_160M: - if (frequencyup) { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_120M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_120M == 0 ? FREQ_SW_120M_START : frequency_MIBand_120M; - } else { - SWMIBandstringold = (String) "" + SWMIBandPosold + " m"; - SWMIBandPos = SW_MI_BAND_11M; - SWMIBandPosold = SWMIBandPos; - SWMIBandstring = (String) "" + SWMIBandPos + " m"; - frequency_AM = frequency_MIBand_11M == 0 ? FREQ_SW_49M_END : frequency_MIBand_11M; - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - break; - } -} - -void SelectBand() { - if (afscreen || advancedRDS || rdsstatscreen) { - BuildDisplay(); - freq_in = 0; - } - - if (band > BAND_GAP) { - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - if (tunemode == TUNE_MI_BAND && band != BAND_SW) tunemode = TUNE_MAN; - BWreset = true; - BWset = BWsetAM; - switch (band) { - case BAND_LW: freqold = frequency_LW; frequency_AM = frequency_LW; break; - case BAND_MW: freqold = frequency_MW; frequency_AM = frequency_MW; break; - case BAND_SW: freqold = frequency_SW; frequency_AM = frequency_SW; break; - } - LimitAMFrequency(); - if (!externaltune && tunemode != TUNE_MEM) CheckBandForbiddenAM(); - radio.SetFreqAM(frequency_AM); - radio.setAMAttenuation(amgain); - radio.setAMCoChannel(amcodect, amcodectcount); - doBW(); - if (!screenmute) { - if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, GreyoutColor, BackgroundColor); - else { - tftPrint16(ALEFT, "PI", 212, 184, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "ID", 212, 201, GreyoutColor, BackgroundColor); - } - - tftPrint16(ALEFT, "PS", 3, 193, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "RT", 3, 221, GreyoutColor, BackgroundColor); - tftPrint16(ALEFT, "PTY", 3, 163, GreyoutColor, BackgroundColor); - tft.drawBitmap(68, 5, RDSLogo, 35, 22, GreyoutColor); - tft.fillRoundRect(249, 57, 30, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "iMS", 265, 59, BackgroundColor, GreyoutColor); - tft.fillRoundRect(287, 57, 30, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "EQ", 301, 59, BackgroundColor, GreyoutColor); - tftReplace(ALEFT, "MHz", "kHz", 258, 76, ActiveColor, ActiveColorSmooth, BackgroundColor, 28); - } - } else { - if (tunemode == TUNE_MI_BAND) tunemode = TUNE_MAN; - - if (!leave) { - if (band == BAND_FM) radio.SetFreq(frequency); - if (band == BAND_OIRT) radio.SetFreq(frequency_OIRT); - } - - BWreset = true; - BWset = BWsetFM; - freqold = frequency_AM; - if (!externaltune && tunemode != TUNE_MEM) CheckBandForbiddenFM(); - doBW(); - if (radio.rds.region == 0) tftPrint16(ALEFT, "PI", 212, 193, ActiveColor, ActiveColorSmooth); - else { - tftPrint16(ALEFT, "PI", 212, 184, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "ID", 212, 201, ActiveColor, ActiveColorSmooth); - } - tftPrint16(ALEFT, "PS", 3, 193, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "RT", 3, 221, ActiveColor, ActiveColorSmooth); - tftPrint16(ALEFT, "PTY", 3, 163, ActiveColor, ActiveColorSmooth); - - tftReplace(ALEFT, "kHz", "MHz", 258, 76, ActiveColor, ActiveColorSmooth, BackgroundColor, 28); - } - - if (!leave) radio.clearRDS(); - ShowFreq(0); - - if (!screenmute) { - tft.fillRect(113, 38, 124, 4, BackgroundColor); - ShowErrors(); - showPTY(); - showRadioText(); - showPI(); - updateiMS(); - updateEQ(); - ShowTuneMode(); - ShowStepSize(); - - tftPrint(ALEFT, textUI(99), 70, 32, BackgroundColor, BackgroundColor, 16); - tftPrint(ALEFT, textUI(100), 70, 32, BackgroundColor, BackgroundColor, 16); - tftPrint(ALEFT, textUI(101), 70, 32, BackgroundColor, BackgroundColor, 16); - tftPrint(ALEFT, textUI(102), 70, 32, BackgroundColor, BackgroundColor, 16); - tftPrint(ALEFT, textUI(103), 70, 32, BackgroundColor, BackgroundColor, 16); - - switch (band) { - case BAND_LW: tftPrint(ALEFT, textUI(99), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; - case BAND_MW: tftPrint(ALEFT, textUI(100), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; - case BAND_SW: tftPrint(ALEFT, textUI(101), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; - case BAND_FM: tftPrint(ALEFT, textUI(102), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; - case BAND_OIRT: tftPrint(ALEFT, textUI(103), 70, 32, (bandforbidden ? GreyoutColor : PrimaryColor), (bandforbidden ? BackgroundColor : PrimaryColorSmooth), 16); break; - } - } - leave = false; -} - -void ModeButtonPress() { - if (seek) radio.setUnMute(); - seek = false; - if (scandxmode) { - ShowFreq(5); - ShowFreq(0); - } else { - if (!usesquelch) radio.setUnMute(); - if (advancedRDS) { - BuildDisplay(); - freq_in = 0; - SelectBand(); - screensavertimer = millis(); - } else if (afscreen) { - if (afpagenr == 1) afpagenr = 2; else if (afpagenr == 2 && afpage) afpagenr = 3; else afpagenr = 1; - BuildAFScreen(); - freq_in = 0; - } else if (rdsstatscreen) { - BuildAFScreen(); - freq_in = 0; - } else { - if (!BWtune && !menu) { - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - memorystore = false; - unsigned long counterold = millis(); - unsigned long counter = millis(); - while (digitalRead(MODEBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); - - if (counter - counterold <= 1000) { - doTuneMode(); - } else { - if (!BWtune && !menu) { - menuoption = ITEM1; - menupage = INDEX; - menuitem = 0; - if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); - BuildMenu(); - freq_in = 0; - menu = true; - } - } - } else { - if (menuopen && !submenu) { - ButtonPress(); - } else if (!submenu) { - OStatusold = 1000; - Stereostatusold = false; - SStatusold = 2000; - BWOld = 0; - if (frequency % 10 != 0) { - if (fmdefaultstepsize == 1) Round100K(frequency); else Round50K(frequency); - EEPROM.writeUInt(EE_UINT16_FREQUENCY_FM, frequency); - } - CheckBandForbiddenFM(); - CheckBandForbiddenAM(); - if (!usesquelch) radio.setUnMute(); - MWLowEdgeSet = mwstepsize == false ? FREQ_MW_LOW_EDGE_MIN_9K : FREQ_MW_LOW_EDGE_MIN_10K; - MWHighEdgeSet = mwstepsize == false ? FREQ_MW_HIGH_EDGE_MAX_9K : FREQ_MW_HIGH_EDGE_MAX_10K; - doBandSelectionFM(); - doBandSelectionAM(); - screensavertimer = millis(); - endMenu(); - } else { - if (submenu) { - if (menuopen) { - if (menupage == CONNECTIVITY && menuoption == ITEM2 && wifi) { - tryWiFi(); - delay(1750); - } - if (menupage == DISPLAYSETTINGS && menuoption == ITEM5) doTheme(); - menuopen = false; - } - submenu = false; - menuoption = ITEM1; - menupage = INDEX; - menuitem = 0; - if (language == LANGUAGE_CHS) PSSprite.setTextFont(1); else PSSprite.setTextFont(0); - BuildMenu(); - freq_in = 0; - } - } - } - } - } - while (digitalRead(MODEBUTTON) == LOW) delay(50); - delay(75); -} - -void RoundStep() { - if (band == BAND_FM) { - unsigned int freq = frequency; - switch (fmdefaultstepsize) { - case 0: Round50K(freq); break; - case 1: Round100K(freq); break; - case 2: Round200K(freq); break; - } - radio.SetFreq(frequency); - } else if (band == BAND_OIRT) { - Round30K(frequency_OIRT); - radio.SetFreq(frequency_OIRT); - } else { - if (band == BAND_LW) { - unsigned int freq = frequency_AM / (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); - frequency_AM = freq * (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); - frequency_LW = frequency_AM; - radio.SetFreqAM(frequency_AM); - } else if (band == BAND_MW) { - unsigned int freq = frequency_AM / (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); - frequency_AM = freq * (mwstepsize == false ? FREQ_MW_STEP_9K : FREQ_MW_STEP_10K); - frequency_MW = frequency_AM; - radio.SetFreqAM(frequency_AM); - } else if (band == BAND_SW) { - Round5K(frequency_AM); - frequency_SW = frequency_AM; - radio.SetFreqAM(frequency_AM); - } - } - - StoreFrequency(); - - while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); -} - -void ButtonPress() { - if (seek) radio.setUnMute(); - seek = false; - if (scandxmode) { - ShowFreq(5); - ShowFreq(0); - } else { - if (!usesquelch) radio.setUnMute(); - if (advancedRDS) { - BuildDisplay(); - freq_in = 0; - SelectBand(); - } - if (!BWtune && !menu) { - if (tunemode == TUNE_MEM) { - if (!memorystore) { - memorystore = true; - if (!IsStationEmpty()) memoryposstatus = MEM_EXIST; - else memoryposstatus = MEM_NORMAL; - ShowMemoryPos(); - - ShowTuneMode(); - } else { - memorystore = false; - StoreMemoryPos(memorypos); - - ShowTuneMode(); - if (memoryposstatus == MEM_DARK || memoryposstatus == MEM_EXIST) { - memoryposstatus = MEM_NORMAL; - ShowMemoryPos(); - } - } - } else { - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - unsigned long counterold = millis(); - unsigned long counter = millis(); - while (digitalRead(ROTARY_BUTTON) == LOW && counter - counterold <= 1000) counter = millis(); - - if (counter - counterold < 1000) { - if (tunemode == TUNE_MAN) { - stepsize++; - if((band == BAND_SW || band < BAND_GAP) && stepsize > 4) stepsize = 0; - else if(stepsize > 3) stepsize = 0; - - if (!screenmute) ShowStepSize(); - - EEPROM.writeByte(EE_BYTE_STEPSIZE, stepsize); - EEPROM.commit(); - if (stepsize == 0) { - RoundStep(); - ShowFreq(0); - } - } - } else { - if (band < BAND_GAP) { - switch (addRowToCSV()) { - case 0: ShowFreq(2); break; - case 1: ShowFreq(3); break; - case 2: ShowFreq(4); break; - } - delay(DELAY_UI_UPDATE_MS); - EdgeBeeper(); - while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); - ShowFreq(0); - } else { - if (band == BAND_SW && tunemode != TUNE_MEM) { - nowToggleSWMIBand = !nowToggleSWMIBand; - tunemode = TUNE_MAN; - EEPROM.writeByte(EE_BYTE_BANDAUTOSW, nowToggleSWMIBand); - EEPROM.commit(); - if (!screenmute) { - tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, BackgroundColor); - tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, BackgroundColor); - } - doTuneMode(); - ShowTuneMode(); - } - } - } - } - screensavertimer = millis(); - } else { - if (menu) DoMenu(); - if (BWtune) { - if (BWsettemp == 18 || BWsettemp == 19) { - if (BWsettemp == 18) iMSset = !iMSset; - if (BWsettemp == 19) EQset = !EQset; - if(!iMSset && !EQset) iMSEQ = 0; - else if(iMSset && EQset) iMSEQ = 2; - else if(!iMSset && EQset) iMSEQ = 3; - else iMSEQ = 4; - EEPROM.writeByte(EE_BYTE_IMSSET, iMSset); - EEPROM.writeByte(EE_BYTE_EQSET, EQset); - EEPROM.commit(); - updateiMS(); - updateEQ(); - if (XDRGTKUSB || XDRGTKTCP) DataPrint("G" + String(!EQset) + String(!iMSset) + "\n"); - showBWSelector(); - if (band < BAND_GAP) drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsFM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); - else drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsAM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); - } else if (BWsettemp == 20) { - BuildDisplay(); - freq_in = 0; - SelectBand(); - } else { - doBW(); - showBWSelector(); - if (band < BAND_GAP) drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsFM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); - else drawButton((BWsettemp == 20 ? "OK" : BWButtonLabelsAM[BWsettemp - 1]), BWsettemp - 1, (BWset == BWsettemp || (BWsettemp == 17 && BWset == 0) || (BWsettemp == 18 && !iMSset) || (BWsettemp == 19 && !EQset) ? true : false), true); - } - } - } - } - while (digitalRead(ROTARY_BUTTON) == LOW) delay(50); -} - -void KeyUp() { - rotary = 0; - if (scandxmode) { - ShowFreq(5); - ShowFreq(0); - } else { - if (!afscreen && !rdsstatscreen) { - if (!BWtune && !menu) { - switch (tunemode) { - case TUNE_MAN: - TuneUp(); - break; - case TUNE_AUTO: - direction = true; - seek = true; - seekinit = true; - Seek(direction); - break; - case TUNE_MEM: - memorypos++; - if (memorypos > EE_PRESETS_CNT - 1) memorypos = 0; - if (!memorystore) { - while (IsStationEmpty()) { - memorypos++; - if (memorypos > EE_PRESETS_CNT - 1) { - memorypos = 0; - break; - } - } - } - if (!memorystore) DoMemoryPosTune(); - else { - if (!IsStationEmpty()) memoryposstatus = MEM_EXIST; else memoryposstatus = MEM_DARK; - } - ShowMemoryPos(); - EEPROM.writeByte(EE_BYTE_MEMORYPOS, memorypos); - EEPROM.commit(); - break; - - case TUNE_MI_BAND: - if (showSWMIBand) { - if (displayflip) ToggleSWMIBand(true); - else ToggleSWMIBand(REVERSE); - } - break; - } - if (XDRGTKUSB || XDRGTKTCP) { - if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); - } - if (!memorystore) { - if (!memtune) radio.clearRDS(); - memtune = false; - ShowFreq(0); - store = true; - } - } else MenuUpDown(true); - } - } -} - -void KeyDown() { - rotary = 0; - if (scandxmode) { - ShowFreq(5); - ShowFreq(0); - } else { - if (!afscreen && !rdsstatscreen) { - if (!BWtune && !menu) { - switch (tunemode) { - case TUNE_MAN: - TuneDown(); - break; - - case TUNE_AUTO: - direction = false; - seek = true; - seekinit = true; - Seek(direction); - break; - - case TUNE_MEM: - memorypos--; - if (memorypos > EE_PRESETS_CNT - 1) memorypos = EE_PRESETS_CNT - 1; - if (!memorystore) { - while (IsStationEmpty()) { - memorypos--; - if (memorypos > EE_PRESETS_CNT - 1) { - memorypos = EE_PRESETS_CNT - 1; - break; - } - } - } - if (!memorystore) DoMemoryPosTune(); - else { - if (!IsStationEmpty()) memoryposstatus = MEM_EXIST; else memoryposstatus = MEM_DARK; - } - ShowMemoryPos(); - EEPROM.writeByte(EE_BYTE_MEMORYPOS, memorypos); - EEPROM.commit(); - break; - case TUNE_MI_BAND: - if (showSWMIBand) { - if (displayflip) ToggleSWMIBand(REVERSE); - else ToggleSWMIBand(true); - } - break; - } - if (XDRGTKUSB || XDRGTKTCP) { - if (band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if (band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); - } - if (!memorystore) { - if (!memtune) radio.clearRDS(); - memtune = false; - ShowFreq(0); - store = true; - } - } else MenuUpDown(false); - } - } -} - -void ShowMemoryPos() { - if (tunemode == TUNE_MEM) { - int memposcolor = 0; - int memposcolorsmooth = 0; - - if (!memorystore) { - if (IsStationEmpty()) memoryposstatus = MEM_DARK; else memoryposstatus = MEM_NORMAL; - } - - switch (memoryposstatus) { - case MEM_DARK: - memposcolor = InsignificantColor; - memposcolorsmooth = InsignificantColorSmooth; - break; - - case MEM_NORMAL: - memposcolor = PrimaryColor; - memposcolorsmooth = PrimaryColorSmooth; - break; - - case MEM_EXIST: - memposcolor = SignificantColor; - memposcolorsmooth = SignificantColorSmooth; - break; - } - if (advancedRDS) tftReplace(ALEFT, String(memoryposold + 1), String(memorypos + 1), 215, 36, SecondaryColor, SecondaryColorSmooth, BackgroundColor, 16); - else tftReplace(ALEFT, String(memoryposold + 1), String(memorypos + 1), 50, 32, memposcolor, memposcolorsmooth, BackgroundColor, 16); - memoryposold = memorypos; - } else { - if (advancedRDS) tftPrint16(ALEFT, String(memorypos + 1), 215, 36, BackgroundColor, BackgroundColor); - else tftPrint16(ALEFT, String(memorypos + 1), 50, 32, BackgroundColor, BackgroundColor); - } -} - -void DoMemoryPosTune() { - radio.clearRDS(); - - if (IsStationEmpty()) { - memoryposstatus = MEM_DARK; - return; - } else memoryposstatus = MEM_NORMAL; - - if (band != presets[memorypos].band) { - band = presets[memorypos].band; - SelectBand(); - } else band = presets[memorypos].band; - - switch (band) { - case BAND_FM: - frequency = presets[memorypos].frequency; - radio.SetFreq(frequency); - break; - case BAND_OIRT: - frequency_OIRT = presets[memorypos].frequency; - radio.SetFreq(frequency_OIRT); - break; - case BAND_LW: - frequency_LW = presets[memorypos].frequency; - radio.SetFreqAM(frequency_LW); - break; - case BAND_MW: - frequency_MW = presets[memorypos].frequency; - radio.SetFreqAM(frequency_MW); - break; - case BAND_SW: - frequency_SW = presets[memorypos].frequency; - radio.SetFreqAM(frequency_SW); - break; - } - - if (band == BAND_FM || band == BAND_OIRT) { - StereoToggle = presets[memorypos].ms; - if (!StereoToggle) { - Stereostatusold = false; - tft.drawBitmap(32, 5, Stereo, 32, 22, BackgroundColor); - tft.drawBitmap(38, 5, Mono, 22, 22, SecondaryColor); - } else { - Stereostatusold = false; - tft.drawBitmap(38, 5, Mono, 22, 22, BackgroundColor); - tft.drawBitmap(32, 5, Stereo, 32, 22, GreyoutColor); - } - } - - if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); - if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); - if (XDRGTKUSB || XDRGTKTCP) DataPrint("T" + String((frequency + ConverterSet * 100) * 10) + "\n"); - - String stationName = ""; - if (presets[memorypos].RDSPS[0] != '\0') { - for (byte i = 0; i < 9; i++) stationName += presets[memorypos].RDSPS[i]; - } - - if (presets[memorypos].RDSPI[0] != '\0') { - for (byte i = 0; i < 4; i++) radio.rds.picode[i] = presets[memorypos].RDSPI[i]; - radio.rds.picode[4] = ' '; - radio.rds.picode[5] = ' '; - radio.rds.picode[6] = '\0'; - radio.rds.correctPI = (uint16_t)strtol(radio.rds.picode, NULL, 16); - } else { - for (byte i = 0; i < 6; i++) radio.rds.picode[i] = '\0'; - } - - radio.rds.stationName = stationName; - - BWset = presets[memorypos].bw; - doBW(); - memtune = true; - memreset = true; - rdsflagreset = false; - findMemoryAF = true; - ShowFreq(0); -} - -void ShowFreq(int mode) { - if (!setupmode) { - if (band != BAND_FM && band != BAND_OIRT) { - if (freqold < 2000 && frequency_AM >= 2000 && stepsize == 0) if (frequency_AM != 27000 && freqold != 144) radio.SetFreqAM(2000); - if (freqold >= 2000 && frequency_AM < 2000 && stepsize == 0) if (frequency_AM != 144 && freqold != 27000) radio.SetFreqAM(1998); - } - } - - if (band > BAND_GAP) { - switch (band) { - case BAND_LW: frequency_AM = frequency_LW; break; - case BAND_MW: frequency_AM = frequency_MW; break; - case BAND_SW: frequency_AM = frequency_SW; break; - } - - if (!screenmute) { - FrequencySprite.fillSprite(BackgroundColor); - FrequencySprite.setTextDatum(TR_DATUM); - FrequencySprite.setTextColor(FreqColor, FreqColorSmooth, false); - FrequencySprite.drawString(String(frequency_AM) + " ", 218, -6, freqfont); - FrequencySprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); - FrequencySprite.setTextDatum(TL_DATUM); - - if (band == BAND_SW && showSWMIBand) { - DivdeSWMIBand(); - updateSWMIBand(); - } - - FrequencySprite.pushSprite(46, 46); - } - - freqold = frequency_AM; - } else { - unsigned int freq = 0; - if (band == BAND_FM) freq = frequency + ConverterSet * 100; - if (band == BAND_OIRT) freq = frequency_OIRT; - - if (!screenmute) { - if (advancedRDS) { - for (int i = 0; i < 33; i++) tft.fillCircle((6 * i) + 10, 133, 2, GreyoutColor); - tftReplace(ARIGHT, String(freqold / 100) + "." + (freqold % 100 < 10 ? "0" : "") + String(freqold % 100), String(freq / 100) + "." + (freq % 100 < 10 ? "0" : "") + String(freq % 100), 273, 35, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); - freqold = freq; - } else if (afscreen) { - tftReplace(ARIGHT, String(freqold / 100) + "." + (freqold % 100 < 10 ? "0" : "") + String(freqold % 100) + " MHz", String(freq / 100) + "." + (freq % 100 < 10 ? "0" : "") + String(freq % 100), 290, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16); - freqold = freq; - } else { - FrequencySprite.fillSprite(BackgroundColor); - - if (mode == 0) { - FrequencySprite.setTextDatum(TR_DATUM); - FrequencySprite.setTextColor(FreqColor, FreqColorSmooth, false); - } else { - FrequencySprite.setTextDatum(TC_DATUM); - FrequencySprite.setTextColor(ActiveColor, ActiveColorSmooth, false); - } - - switch (mode) { - case 0: - FrequencySprite.drawString(String(freq / 100) + "." + (freq % 100 < 10 ? "0" : "") + String(freq % 100) + " ", 218, -6, freqfont); - freqold = freq; - break; - case 1: Infoboxprint(textUI(31)); break; - case 2: Infoboxprint(textUI(286)); break; - case 3: Infoboxprint(textUI(287)); break; - case 4: Infoboxprint(textUI(291)); break; - case 5: Infoboxprint(textUI(280)); break; - } - - FrequencySprite.pushSprite(46, 46); - if (mode == 5) delay(1000); - } - } - } - - rdsreset = true; - afmethodBold = false; - aid_counterold = 0; - dropout = false; - - if (wifi) { - Udp.beginPacket(remoteip, 9030); - if (band == BAND_FM) Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";freq=" + String(frequency) + "0000"); - else if (band == BAND_OIRT) Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";freq=" + String(frequency_OIRT) + "0000"); - else Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";freq=" + String(frequency_AM) + "000"); - Udp.endPacket(); - } - tuningtimer = millis(); - - if (!rdsflagreset && !screenmute && !afscreen && !rdsstatscreen) { - ShowRDSLogo(false); - if (!advancedRDS) { - FullLineSprite.fillSprite(BackgroundColor); - FullLineSprite.drawLine(283, 0, 283, 19, FrameColor); - FullLineSprite.pushSprite(36, 220); - tft.fillCircle(314, 223, 2, GreyoutColor); - tft.fillCircle(314, 234, 2, GreyoutColor); - } else { - GeneralTextSprite.fillSprite(TFT_TRANSPARENT); - GeneralTextSprite.fillRect(0, 0, 165, 19, BackgroundColor); - GeneralTextSprite.pushSprite(36, 220, TFT_TRANSPARENT); - tft.fillCircle(314, 223, 2, GreyoutColor); - tft.fillCircle(314, 234, 2, GreyoutColor); - } - rdsflagreset = true; - } -} - -void ShowSignalLevel() { - SAvg = (((SAvg * 9) + 5) / 10) + SStatus; - SAvg2 = (((SAvg2 * 9) + 5) / 10) + CN; - SAvg4 = (((SAvg4 * 9) + 5) / 10) + WAM; - SAvg5 = (((SAvg5 * 9) + 5) / 10) + USN; - - SStatus = SAvg / 10; - CN = SAvg2 / 10; - MP = SAvg4 / 10; - US = SAvg5 / 10; - - if (!screenmute) { - if (millis() >= SNRupdatetimer + TIMER_SNR_TIMER) { - SNRupdatetimer = millis(); - if (!advancedRDS) { - if (CN > (CNold + 1) || CN < (CNold - 1)) { - if (CNold == 0) tftPrint16(ARIGHT, "--", 234, 165, BackgroundColor, BackgroundColor); else tftPrint16(ARIGHT, String(CNold), 234, 165, BackgroundColor, BackgroundColor); - if (tuned) { - if (CN == 0) tftPrint16(ARIGHT, "--", 234, 165, PrimaryColor, PrimaryColorSmooth); else tftPrint16(ARIGHT, String(CN), 234, 165, PrimaryColor, PrimaryColorSmooth); - CNold = CN; - } else { - tftPrint16(ARIGHT, "--", 234, 165, PrimaryColor, PrimaryColorSmooth); - CNold = 0; - } - } - - byte MPprint = constrain(map(MP, 0, 1000, 0, 99), 0, 99); - if (MPprint != MPold) { - tftReplace(ARIGHT, String(MPold), (band < BAND_GAP ? String(MPprint) : "--"), 299, 165, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); - MPold = MPprint; - } - - byte USprint = constrain(map(US, 0, 1000, 0, 99), 0, 99); - if (USprint != USold) { - tftReplace(ARIGHT, String(USold), (band < BAND_GAP ? String(USprint) : "--"), 299, 147, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); - USold = USprint; - } - } - } - - int SStatusprint = 0; - if (unit == 0) SStatusprint = SStatus; - if (unit == 1) SStatusprint = ((SStatus * 100) + 10875) / 100; - if (unit == 2) SStatusprint = round((float(SStatus) / 10.0 - 10.0 * log10(75) - 90.0) * 10.0); - - static int DisplayedSignalSegments = 0; - if (SStatusprint > (SStatusold + 3) || SStatusprint < (SStatusold - 3)) { - if (advancedRDS) tftReplace(ARIGHT, String(SStatusold / 10) + "." + String(abs(SStatusold % 10)), String(SStatusprint / 10) + "." + String(abs(SStatusprint % 10)), 273, 51, PrimaryColor, PrimaryColorSmooth, BackgroundColor, 16); - else { - if (SStatusold / 10 != SStatusprint / 10) tftReplace(ARIGHT, String(SStatusold / 10), String(SStatusprint / 10), 280, 104, FreqColor, FreqColorSmooth, BackgroundColor, 48); - tftReplace(ALEFT, "." + String(abs(SStatusold % 10)), "." + String(abs(SStatusprint % 10)), 285, 102, FreqColor, FreqColorSmooth, BackgroundColor, 28); - - // Calculate segments for signal meter - if (band < BAND_GAP) DisplayedSignalSegments = constrain(map(SStatus / 10, 0, 70, 0, 100), 0, 87); - else DisplayedSignalSegments = constrain((SStatus + 200) / 10, 0, 87); - - HSV hsv1 = RGB565toHSV(BarInsignificantColor); - HSV hsv2 = RGB565toHSV(BarSignificantColor); - - int gradientStart = (87 * 25) / 100; - int gradientEnd = (87 * 60) / 100; - - // Draw solid color for first 25% - for (int i = 0; i < min(DisplayedSignalSegments, gradientStart); i++) tft.fillRect(16 + 2 * i, 105, 2, 6, BarInsignificantColor); - - if (DisplayedSignalSegments > gradientStart) { - for (int i = gradientStart; i < min(DisplayedSignalSegments, gradientEnd); i++) { - float h = map(i, gradientStart, gradientEnd, hsv1.h, hsv2.h); - float s = map(i, gradientStart, gradientEnd, hsv1.s * 100, hsv2.s * 100) / 100.0; - float v = map(i, gradientStart, gradientEnd, hsv1.v * 100, hsv2.v * 100) / 100.0; - tft.fillRect(16 + 2 * i, 105, 2, 6, HSVtoRGB565(h, s, v)); - } - } - - if (DisplayedSignalSegments > gradientEnd) { - for (int i = gradientEnd; i < DisplayedSignalSegments; i++) tft.fillRect(16 + 2 * i, 105, 2, 6, BarSignificantColor); - } - - int greyStart = 16 + 2 * DisplayedSignalSegments; - int greyWidth = 2 * (87 - DisplayedSignalSegments); - tft.fillRect(greyStart, 105, greyWidth, 6, GreyoutColor); - } - - SStatusold = SStatusprint; - } - } - - if (!seek) { - if (tuned && CN > 15 && SStatus > 300) { - if (!setextendbw) { - setextendbw = true; - radio.extendBW(true); - } - } else { - if (setextendbw) { - setextendbw = false; - radio.extendBW(false); - } - } - } - - if (wifi && millis() >= udptimer + 2000) { - udptimer = millis(); - Udp.beginPacket(remoteip, 9030); - Udp.print("from=TEF_tuner_" + String(stationlistid, DEC) + ";RcvLevel=" + String(SStatus / 10)); - Udp.endPacket(); - } -} - -void ShowOffset() { - if (OStatus != OStatusold) { - if (millis() >= offsetupdatetimer + TIMER_OFFSET_TIMER) offsetupdatetimer = millis(); - else return; - - int baseX = 13; // Left boundary - int baseY = 2; // Top boundary - int width = 4; // Max width - int height = 26; // Max height - - int centerX = baseX + width / 2; // Center dot X - int centerY = baseY + height / 2; // Center dot Y - - // **Move arrows 3px further from the dot** - int arrowGap = 3; // Space between dot and arrows - int arrowWidth = 9; // Arrow stretch size - int leftArrowBaseX = centerX - arrowWidth - arrowGap; // Shift left arrow further left - int rightArrowBaseX = centerX + arrowWidth + arrowGap; // Shift right arrow further right - - int arrowBaseYTop = baseY + 1; // Adjusted top Y position - int arrowBaseYBottom = baseY + height - 1; - - if (band < BAND_GAP) { - if (OStatus < -250) { - // Left arrow active (▶) - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); - // Center dot - tft.fillCircle(centerX, centerY, 3, GreyoutColor); - // Right arrow dimmed (◀) - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, SignificantColor); - tuned = false; - } else if (USN < 250 && WAM < 250 && OStatus > -250 && OStatus < 250 && !SQ) { - // Both arrows dimmed - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); - // Center dot active - tft.fillCircle(centerX, centerY, 3, InsignificantColor); - tuned = true; - } else if (OStatus > 250) { - // Right arrow active (◀) - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); - // Center dot dimmed - tft.fillCircle(centerX, centerY, 3, GreyoutColor); - // Left arrow dimmed (▶) - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, SignificantColor); - tuned = false; - } else { - // Everything dimmed - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillCircle(centerX, centerY, 3, GreyoutColor); - tuned = false; - } - } else { - if (OStatus < -2) { - // Left arrow active (▶) - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillCircle(centerX, centerY, 3, GreyoutColor); - // Right arrow dimmed (◀) - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, SignificantColor); - tuned = false; - } else if (OStatus >= -2 && OStatus <= 2 && !SQ) { - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillCircle(centerX, centerY, 3, InsignificantColor); - tuned = true; - } else if (OStatus > 2) { - // Right arrow active (◀) - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillCircle(centerX, centerY, 3, GreyoutColor); - // Left arrow dimmed (▶) - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, SignificantColor); - tuned = false; - } else { - tft.fillTriangle(leftArrowBaseX, arrowBaseYTop, centerX - arrowGap, centerY, leftArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillTriangle(rightArrowBaseX, arrowBaseYTop, centerX + arrowGap, centerY, rightArrowBaseX, arrowBaseYBottom, GreyoutColor); - tft.fillCircle(centerX, centerY, 3, GreyoutColor); - tuned = false; - } - } - OStatusold = OStatus; - } -} - -void ShowAudioLevel() { - if(showaudio) { - int segments; - MStatus = (MStatus > 120) ? 120 : MStatus; - - if (seek || SQ) MStatus = 0; - - segments = constrain(map(MStatus, 0, 120, 0, 86), 0, 86); - - if (segments < DisplayedSegments && (millis() - AudiopreviousMillis >= 20)) { - DisplayedSegments = max(DisplayedSegments - 3, segments); - AudiopreviousMillis = millis(); - } else if (segments > DisplayedSegments) DisplayedSegments = segments; - - DisplayedSegments = constrain(DisplayedSegments, 0, 86); - - if (DisplayedSegments > peakholdold) { - peakholdold = DisplayedSegments; - peakholdmillis = millis(); - } - - if (millis() - peakholdmillis >= 1000) { - if (millis() - AudiopeakPreviousMillis >= 20) { - peakholdold = max(peakholdold - 3, DisplayedSegments); - AudiopeakPreviousMillis = millis(); - } - } - - peakholdold = constrain(peakholdold, 0, 86); - - HSV hsv1 = RGB565toHSV(ModBarInsignificantColor); - HSV hsv2 = RGB565toHSV(ModBarSignificantColor); - - int gradientStart = (86 * 25) / 100; - int gradientEnd = (86 * 60) / 100; - - for (int i = 0; i < min(DisplayedSegments, gradientStart); i++) tft.fillRect(16 + 2 * i, 133, 2, 6, ModBarInsignificantColor); - - if (DisplayedSegments > gradientStart) { - for (int i = gradientStart; i < min(DisplayedSegments, gradientEnd); i++) { - float h = map(i, gradientStart, gradientEnd, hsv1.h, hsv2.h); - float s = map(i, gradientStart, gradientEnd, hsv1.s * 100, hsv2.s * 100) / 100.0; - float v = map(i, gradientStart, gradientEnd, hsv1.v * 100, hsv2.v * 100) / 100.0; - tft.fillRect(16 + 2 * i, 133, 2, 6, HSVtoRGB565(h, s, v)); - } - } - - if (DisplayedSegments > gradientEnd) { - for (int i = gradientEnd; i < DisplayedSegments; i++) tft.fillRect(16 + 2 * i, 133, 2, 6, ModBarSignificantColor); - } - - int greyStart = 16 + 2 * DisplayedSegments; - int greyWidth = 2 * (87 - DisplayedSegments); - tft.fillRect(greyStart, 133, greyWidth, 6, GreyoutColor); - - int peakHoldPosition = 16 + 2 * peakholdold; - tft.fillRect(peakHoldPosition, 133, 2, 6, (MStatus > 80) ? ModBarSignificantColor : PrimaryColor); - - if (millis() - peakholdmillis >= 1000 && (peakholdold <= DisplayedSegments || peakholdold >= 86)) tft.fillRect(peakHoldPosition, 133, 2, 6, GreyoutColor); - } -} - -void doSquelch() { - if (!XDRGTKUSB && !XDRGTKTCP && usesquelch && !autosquelch) Squelch = map(analogRead(PIN_POT), 0, 4095, -100, 920); - if (Squelch < - 800) Squelch = -100; - if (Squelch > 900) Squelch = 920; - - if (unit == 0) SquelchShow = Squelch / 10; - if (unit == 1) SquelchShow = ((Squelch * 100) + 10875) / 1000; - if (unit == 2) SquelchShow = round(((float)Squelch / 10.0 - 10.0 * log10(75) - 90.0) * 10.0) / 10; - if (Squelch > 920) Squelch = 920; - - if (autosquelch) { - if (band < BAND_GAP) { - if (isSignalQualityGood(USN, WAM, OStatus, SCAN_SIGNAL_THRESHOLD_USN_MULTIPLIER, SCAN_SIGNAL_THRESHOLD_OSTATUS_WIDE) && (!scandxmode || (scandxmode && !scanmute))) { - if (SQ || BWreset) { - if (!seek) radio.setUnMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - autosquelchtimer = millis(); - SQ = false; - } - } else { - if ((!SQ || BWreset) && (millis() >= autosquelchtimer + 1000)) { - radio.setMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - autosquelchtimer = millis(); - SQ = true; - } - } - } else { - if ((USN < amscansens * 30) && (OStatus < 2 && OStatus > -2) && (!scandxmode || (scandxmode && !scanmute))) { - if (!seek) radio.setUnMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - SQ = false; - } else { - radio.setMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - SQ = true; - } - } - } else { - if (!XDRGTKUSB && !XDRGTKTCP && usesquelch && (!scandxmode || (scandxmode && !scanmute))) { - if (!screenmute && usesquelch && !advancedRDS && !afscreen && !rdsstatscreen) { - if (!BWtune && !menu && (Squelch > Squelchold + 2 || Squelch < Squelchold - 2)) { - SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); - SquelchSprite.fillSprite(BackgroundColor); - if (Squelch == -100) SquelchSprite.drawString("--", 0, 0); - else if (Squelch == 920) SquelchSprite.drawString("ST", 0, 0); - else SquelchSprite.drawString(String(SquelchShow), 0, 0); - SquelchSprite.pushSprite(223, 147); - Squelchold = Squelch; - } - } - } - - if ((XDRGTKUSB || XDRGTKTCP) && (!scandxmode || (scandxmode && !scanmute))) { - if (!XDRMute) { - if (Squelch != -1) { - if (Squelch < SStatus || Squelch == -100 || Squelch == 0) { - if (!seek) radio.setUnMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - SQ = false; - } else { - radio.setMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - SQ = true; - } - } else { - if (Stereostatus) { - radio.setUnMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - SQ = false; - } else { - radio.setMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - SQ = true; - } - } - if (!screenmute && usesquelch && !advancedRDS && !afscreen && !rdsstatscreen) { - if (Squelch != Squelchold) { - SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth); - SquelchSprite.fillSprite(BackgroundColor); - - if (Squelch == -1) SquelchSprite.drawString("ST", 0, 0); - else if (Squelch == 0) SquelchSprite.drawString("--", 0, 0); - else SquelchSprite.drawString(String(SquelchShow), 0, 0); - if (Squelch != Squelchold) SquelchSprite.pushSprite(223, 147); - Squelchold = Squelch; - } - } - } - } else if (usesquelch && (!scandxmode || (scandxmode && !scanmute))) { - if (Squelch != 920) { - if (Squelch < SStatus || Squelch == -100 || Squelch == 0) { - if (!seek) radio.setUnMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - SQ = false; - } else { - radio.setMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - SQ = true; - } - } else { - if (Stereostatus) { - if (!seek) radio.setUnMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - SQ = false; - } else { - radio.setMute(); - if (!screenmute && !seek) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - SQ = true; - } - } - } - } -} - -void doBW() { - if (BWtune && !bwtouchtune) BWset = BWsettemp; - - if (band < BAND_GAP) { - if (BWset > 16) BWset = 0; - - switch (BWset) { - case 1: radio.setFMBandw(56); break; - case 2: radio.setFMBandw(64); break; - case 3: radio.setFMBandw(72); break; - case 4: radio.setFMBandw(84); break; - case 5: radio.setFMBandw(97); break; - case 6: radio.setFMBandw(114); break; - case 7: radio.setFMBandw(133); break; - case 8: radio.setFMBandw(151); break; - case 9: radio.setFMBandw(168); break; - case 10: radio.setFMBandw(184); break; - case 11: radio.setFMBandw(200); break; - case 12: radio.setFMBandw(217); break; - case 13: radio.setFMBandw(236); break; - case 14: radio.setFMBandw(254); break; - case 15: radio.setFMBandw(287); break; - case 16: radio.setFMBandw(311); break; - } - BWsetFM = BWset; - EEPROM.writeByte(EE_BYTE_BWSET_FM, BWsetFM); - - if ((XDRGTKUSB || XDRGTKTCP) && !XDRScan) { - switch (BWset) { - case 0: DataPrint("W0\n"); break; - case 1: DataPrint("W56000\n"); break; - case 2: DataPrint("W64000\n"); break; - case 3: DataPrint("W72000\n"); break; - case 4: DataPrint("W84000\n"); break; - case 5: DataPrint("W97000\n"); break; - case 6: DataPrint("W114000\n"); break; - case 7: DataPrint("W133000\n"); break; - case 8: DataPrint("W151000\n"); break; - case 9: DataPrint("W168000\n"); break; - case 10: DataPrint("W184000\n"); break; - case 11: DataPrint("W200000\n"); break; - case 12: DataPrint("W217000\n"); break; - case 13: DataPrint("W236000\n"); break; - case 14: DataPrint("W254000\n"); break; - case 15: DataPrint("W287000\n"); break; - case 16: DataPrint("W311000\n"); break; - } - } - } else { - if (BWset > 4) BWset = 1; - - switch (BWset) { - case 1: radio.setAMBandw(3); break; - case 2: radio.setAMBandw(4); break; - case 3: radio.setAMBandw(6); break; - case 4: radio.setAMBandw(8); break; - } - BWsetAM = BWset; - EEPROM.writeByte(EE_BYTE_BWSET_AM, BWsetAM); - } - updateBW(); - BWreset = true; - EEPROM.commit(); -} - -void doTuneMode() { - switch (tunemode) { - case TUNE_MAN: - if (band == BAND_SW) { - if (showSWMIBand && nowToggleSWMIBand) tunemode = TUNE_MI_BAND; - else tunemode = TUNE_AUTO; - } else tunemode = TUNE_AUTO; - break; - case TUNE_MI_BAND: - case TUNE_AUTO: - tunemode = TUNE_MEM; - break; - case TUNE_MEM: - if (!bandforbidden) tunemode = TUNE_MAN; - break; - } - ShowTuneMode(); - ShowMemoryPos(); - EEPROM.writeByte(EE_BYTE_TUNEMODE, tunemode); - EEPROM.commit(); -} - -void ShowTuneMode() { - if (!screenmute) { - switch (tunemode) { - case TUNE_MAN: - if (band == BAND_SW && nowToggleSWMIBand) { - tftPrint16(ACENTER, "AUTO", 22, 60, GreyoutColor, GreyoutColor); - tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, GreyoutColor); - } else { - tftPrint16(ACENTER, "BAND", 22, 60, GreyoutColor, GreyoutColor); - tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, GreyoutColor); - } - - tft.fillRoundRect(2, 36, 40, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, SecondaryColor); - - tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); - break; - - case TUNE_AUTO: - tft.fillRoundRect(2, 58, 40, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, SecondaryColor); - - tft.fillRoundRect(2, 36, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, GreyoutColor); - - tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); - break; - - case TUNE_MEM: - if (band == BAND_SW && nowToggleSWMIBand) { - tftPrint16(ACENTER, "AUTO", 22, 60, GreyoutColor, GreyoutColor); - - tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, GreyoutColor); - } else { - tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, GreyoutColor); - - tft.fillRoundRect(2, 58, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "AUTO", 22, 60, BackgroundColor, GreyoutColor); - } - - tft.fillRoundRect(2, 36, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, GreyoutColor); - - if (memorystore) { - tft.fillRoundRect(2, 80, 40, 18, 2, SignificantColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SignificantColor); - } else { - tft.fillRoundRect(2, 80, 40, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, SecondaryColor); - } - break; - - case TUNE_MI_BAND: - tft.fillRoundRect(2, 58, 40, 18, 2, SecondaryColor); - tftPrint16(ACENTER, "BAND", 22, 60, BackgroundColor, SecondaryColor); - - tft.fillRoundRect(2, 36, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "MAN", 22, 38, BackgroundColor, GreyoutColor); - - tft.fillRoundRect(2, 80, 40, 18, 2, GreyoutColor); - tftPrint16(ACENTER, "MEM", 22, 82, BackgroundColor, GreyoutColor); - break; - } - } -} - -void ShowBattery() { - if (millis() >= batupdatetimer + TIMER_BAT_TIMER) batupdatetimer = millis(); - else return; - - float v = analogReadMilliVolts(BATTERY_PIN) * 0.002; // 0.002 converts to volts plus corrects the /2 voltage divider - byte battery = map(constrain(v, BATTERY_LOW_VALUE, BATTERY_FULL_VALUE), BATTERY_LOW_VALUE, BATTERY_FULL_VALUE, 0, BAT_LEVEL_STAGE); - byte batteryprobe = map(constrain(v, BATTERY_LOW_VALUE, BATTERY_FULL_VALUE), BATTERY_LOW_VALUE, BATTERY_FULL_VALUE, 0, 50); - if (batteryold != batteryprobe) { - if (batterydetect) { - if (battery == 0) { - tft.drawRoundRect(277, 6, 37, 20, 2, BarSignificantColor); - tft.fillRoundRect(313, 13, 4, 6, 2, BarSignificantColor); - } else { - tft.drawRoundRect(277, 6, 37, 20, 2, ActiveColor); - tft.fillRoundRect(313, 13, 4, 6, 2, ActiveColor); - } - - if (batteryoptions != BATTERY_VALUE && batteryoptions != BATTERY_PERCENT && battery != 0) { - if(v > BATTERY_FULL_VALUE) tft.fillRoundRect(279, 8, 32, 16, 2, ActiveColor); - else tft.fillRoundRect(279, 8, battery * 8, 16, 2, SecondaryColor); - } else tft.fillRoundRect(279, 8, 32, 16, 2, BackgroundColor); - } - batteryold = batteryprobe; - batteryVold = 0; - vPerold = 0; - - if (batterydetect) { - float vPer = constrain((v - BATTERY_LOW_VALUE) / (BATTERY_FULL_VALUE - BATTERY_LOW_VALUE), 0.0, 1.0) * 100.0; - if (abs(v - batteryVold) > 0.05 && batteryoptions == BATTERY_VALUE) { - tftPrint(ALEFT, String(v, 2) + "V", 279, 9, BatteryValueColor, BatteryValueColorSmooth, 16); - batteryVold = v; - } else if (int(vPer) != int(vPerold) && batteryoptions == BATTERY_PERCENT && abs(vPer - vPerold) > 0.5) { - tftPrint(ALEFT, String(vPer, 0) + "%", 279, 9, BatteryValueColor, BatteryValueColorSmooth, 16); - vPerold = vPer; - } - } - } -} - -void TuneUp() { - aftest = true; - aftimer = millis(); - unsigned int temp = 0; - if (stepsize == 0) { - if (band > BAND_GAP) { - if (frequency_AM <= MWHighEdgeSet && frequency_AM >= MWLowEdgeSet) { - if (!mwstepsize) { - temp = FREQ_MW_STEP_9K; - frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; - } else if (mwstepsize) { - temp = FREQ_MW_STEP_10K; - frequency_AM = (frequency_AM / FREQ_MW_STEP_10K) * FREQ_MW_STEP_10K; - } - } else if (frequency_AM < MWLowEdgeSet) { - temp = FREQ_MW_STEP_9K; - frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; - } else if (frequency_AM <= SWHighEdgeSet && frequency_AM >= SWLowEdgeSet) { - temp = FREQ_SW_STEP_5K; - frequency_AM = (frequency_AM / FREQ_SW_STEP_5K) * FREQ_SW_STEP_5K; - } - } else { - if (band == BAND_OIRT) temp = FREQ_OIRT_STEP_30K; - else { - switch (fmdefaultstepsize) { - case 0: temp = FREQ_FM_STEP_50K; break; - case 1: temp = FREQ_FM_STEP_100K; break; - case 2: temp = FREQ_FM_STEP_200K; break; - } - } - } - } - if (stepsize == 1) temp = 1; - else if (stepsize == 2) temp = 10; - else if (stepsize == 3) temp = 100; - else if (stepsize == 4) temp = 1000; - if (rotaryaccelerate && rotarycounter > 2) temp *= 2; - - if (band == BAND_FM) { - frequency += temp; - if (scandxmode) { - while (IsFrequencyUsed(frequency) || presets[memorypos].band != BAND_FM) frequency += temp; - } - - if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8795) frequency = 8790; - if (frequency >= (HighEdgeSet * 10) + 1) { - frequency = LowEdgeSet * 10; - if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8750) frequency = 8775; - EdgeBeeper(); - } - radio.SetFreq(frequency); - } else if (band == BAND_OIRT) { - frequency_OIRT += temp; - if (scandxmode) { - while (IsFrequencyUsed(frequency_OIRT) || presets[memorypos].band != BAND_OIRT) frequency_OIRT += temp; - } - if (frequency_OIRT > HighEdgeOIRTSet) { - frequency_OIRT = LowEdgeOIRTSet; - EdgeBeeper(); - } - radio.SetFreq(frequency_OIRT); - } else if (band == BAND_LW) { - frequency_AM += temp; - if (frequency_AM > LWHighEdgeSet) { - frequency_AM = LWLowEdgeSet; - EdgeBeeper(); - } - radio.SetFreqAM(frequency_AM); - frequency_LW = frequency_AM; - } else if (band == BAND_MW) { - frequency_AM += temp; - if (frequency_AM > MWHighEdgeSet) { - frequency_AM = MWLowEdgeSet; - EdgeBeeper(); - } - radio.SetFreqAM(frequency_AM); - frequency_MW = frequency_AM; - } else if (band == BAND_SW) { - if (rotaryaccelerate && rotarycounter > 2) temp *= 2; - frequency_AM += temp; - if (frequency_AM > SWHighEdgeSet) { - frequency_AM = SWLowEdgeSet; - EdgeBeeper(); - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - } - radio.clearRDS(); - if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); - if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); -} - -void TuneDown() { - aftest = true; - aftimer = millis(); - unsigned int temp = 0; - if (stepsize == 0) { - if (band > BAND_GAP) { - if (frequency_AM < MWHighEdgeSet && frequency_AM > MWLowEdgeSet) { - if (!mwstepsize) { - temp = FREQ_MW_STEP_9K; - frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; - } else if (mwstepsize) { - temp = FREQ_MW_STEP_10K; - frequency_AM = (frequency_AM / FREQ_MW_STEP_10K) * FREQ_MW_STEP_10K; - } - } else if (frequency_AM < MWLowEdgeSet) { - temp = FREQ_MW_STEP_9K; - frequency_AM = (frequency_AM / FREQ_MW_STEP_9K) * FREQ_MW_STEP_9K; - } else { - temp = FREQ_SW_STEP_5K; - frequency_AM = (frequency_AM / FREQ_SW_STEP_5K) * FREQ_SW_STEP_5K; - } - } else { - if (band == BAND_OIRT) temp = FREQ_OIRT_STEP_30K; - else { - switch (fmdefaultstepsize) { - case 0: temp = FREQ_FM_STEP_50K; break; - case 1: temp = FREQ_FM_STEP_100K; break; - case 2: temp = FREQ_FM_STEP_200K; break; - } - } - } - } - if (stepsize == 1) temp = 1; - else if (stepsize == 2) temp = 10; - else if (stepsize == 3) temp = 100; - else if (stepsize == 4) temp = 1000; - if (rotaryaccelerate && rotarycounter > 2) temp *= 2; - - if (band == BAND_FM) { - frequency -= temp; - if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8770) frequency = 8775; - if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 8755) frequency = 10790; - - if (frequency < LowEdgeSet * 10) { - frequency = HighEdgeSet * 10; - if (fmdefaultstepsize == 2 && stepsize == 0 && frequency == 10800) frequency = 10790; - EdgeBeeper(); - } - radio.SetFreq(frequency); - } else if (band == BAND_OIRT) { - frequency_OIRT -= temp; - if (frequency_OIRT < LowEdgeOIRTSet) { - frequency_OIRT = HighEdgeOIRTSet; - EdgeBeeper(); - } - radio.SetFreq(frequency_OIRT); - } else if (band == BAND_LW) { - frequency_AM -= temp; - if (frequency_AM < LWLowEdgeSet) { - frequency_AM = LWHighEdgeSet; - EdgeBeeper(); - } - radio.SetFreqAM(frequency_AM); - frequency_LW = frequency_AM; - } else if (band == BAND_MW) { - frequency_AM -= temp; - if (frequency_AM < MWLowEdgeSet) { - frequency_AM = MWHighEdgeSet; - EdgeBeeper(); - } - radio.SetFreqAM(frequency_AM); - frequency_MW = frequency_AM; - } else if (band == BAND_SW) { - if (rotaryaccelerate && rotarycounter > 2) temp *= 2; - frequency_AM -= temp; - if (frequency_AM < SWLowEdgeSet) { - frequency_AM = SWHighEdgeSet; - EdgeBeeper(); - } - radio.SetFreqAM(frequency_AM); - frequency_SW = frequency_AM; - } - radio.clearRDS(); - if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); - if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); -} - -void Seek(bool mode) { - radio.setMute(); - if (seekinit) { - if (stepsize != 0) { - stepsize = 0; - RoundStep(); - ShowStepSize(); - } - seekinit = false; - } - - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, PrimaryColor); - if (!mode) TuneDown(); else TuneUp(); - delay(50); - - ShowFreq(0); - if (XDRGTKUSB || XDRGTKTCP) { - if(band == BAND_FM) DataPrint("M0\nT" + String(frequency * 10) + "\n"); else if(band == BAND_OIRT) DataPrint("M0\nT" + String(frequency_OIRT * 10) + "\n"); else DataPrint("M1\nT" + String(frequency_AM) + "\n"); - } - - if (band < BAND_GAP) { - radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - if (isSignalQualityGood(USN, WAM, OStatus) && (!usesquelch || (Squelch < SStatus || Squelch == SQUELCH_MAX_VALUE))) { - seek = false; - radio.setUnMute(); - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - store = true; - } else { - seek = true; - if (RDSSPYUSB) Serial.print("G:\r\nRESET-------\r\n\r\n"); - if (RDSSPYTCP) RemoteClient.print("G:\r\nRESET-------\r\n\r\n"); - } - } else { - radio.getStatusAM(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - if ((USN < amscansens * 30) && (OStatus < 2 && OStatus > -2) && (!usesquelch || (Squelch < SStatus || Squelch == 920))) { - seek = false; - radio.setUnMute(); - if (!screenmute) tft.drawBitmap(249, 4, Speaker, 28, 24, GreyoutColor); - store = true; - } else seek = true; - } -} - -void read_encoder() { - if (!digitalRead(ROTARY_PIN_A) || !digitalRead(ROTARY_PIN_B)) { - uint32_t dt = millis() - rotarytimer; - if (dt >= 45) { - rotarycounteraccelerator = 6; - rotarycounter = 0; - } else if (dt >= 30) { - rotarycounteraccelerator = 4; - rotarycounter = 0; - } else if (dt >= 15) { - rotarycounteraccelerator = 2; - rotarycounter = 0; - } - } - - static uint8_t old_AB = 3; - static int8_t encval = 0; - static const int8_t enc_states[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; - - old_AB <<= 2; - if (digitalRead(ROTARY_PIN_A)) old_AB |= 0x02; - if (digitalRead(ROTARY_PIN_B)) old_AB |= 0x01; - encval += enc_states[old_AB & 0xf]; - if (!(255 - old_AB)) encval = 0; - - if (encval > 3) { - if (rotarymode) rotary = -1; else rotary = 1; - rotarycounter++; - rotarytimer = millis(); - encval = 0; - } else if (encval < -3) { - if (rotarymode) rotary = 1; else rotary = -1; - rotarycounter++; - rotarytimer = millis(); - encval = 0; - } -} - -void tftReplace(int8_t offset, const String & textold, const String & text, int16_t x, int16_t y, int color, int smoothcolor, int background, uint8_t fontsize) { - uint8_t selectedFont = 0 ? (language == LANGUAGE_CHS) : 2; - if(fontsize == 28) selectedFont = (language == LANGUAGE_CHS) ? 4 : 3; - else if(fontsize == 48) selectedFont = 1; - - switch (offset) { - case -1: tft.setTextDatum(TL_DATUM); break; - case 0: tft.setTextDatum(TC_DATUM); break; - case 1: tft.setTextDatum(TR_DATUM); break; - } - - tft.setTextColor(background, background, false); - tft.drawString(textold, x, y, selectedFont); - - String modifiedText = text; - modifiedText.replace("\n", " "); - - tft.setTextColor(color, smoothcolor, false); - tft.drawString(modifiedText, x, y, selectedFont); -} - -void tftPrint(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, uint8_t fontsize) { - uint8_t selectedFont = (language == LANGUAGE_CHS) ? 0 : 2; - if (fontsize == 28) selectedFont = (language == LANGUAGE_CHS) ? 4 : 3; - else if (fontsize == 48) selectedFont = 1; - - tft.setTextColor(color, smoothcolor); - - switch (offset) { - case -1: tft.setTextDatum(TL_DATUM); break; - case 0: tft.setTextDatum(TC_DATUM); break; - case 1: tft.setTextDatum(TR_DATUM); break; - } - - String modifiedText = text; - modifiedText.replace("\n", " "); - - tft.drawString(modifiedText, x, y, selectedFont); -} - -void tftPrint16(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, bool force_font, bool font) { - uint8_t selectedFont = (language == LANGUAGE_CHS) ? 0 : 2; - if(force_font) selectedFont = 0 ? font : 2; - - tft.setTextColor(color, smoothcolor); - - switch (offset) { - case -1: tft.setTextDatum(TL_DATUM); break; - case 0: tft.setTextDatum(TC_DATUM); break; - case 1: tft.setTextDatum(TR_DATUM); break; - } - - String modifiedText = text; - modifiedText.replace("\n", " "); - - tft.drawString(modifiedText, x, y, selectedFont); -} - -void UpdateFonts() { - // This is at setup: - // tft.loadFont(FONT48, 1); - - // tft.loadFont(FONT16_CHS, 0); - // tft.loadFont(FONT16, 2); - // tft.loadFont(FONT28, 3); - // tft.loadFont(FONT28_CHS, 4); - - if (language == LANGUAGE_CHS) { - if (menu) PSSprite.setTextFont(1); else PSSprite.setTextFont(3); - OneBigLineSprite.copyFontFromTFT(4, 0); - FullLineSprite.copyFontFromTFT(0, 0); - GeneralTextSprite.copyFontFromTFT(0, 0); - GeneralTextSprite.copyFontFromTFT(4, 1); - FrequencySprite.copyFontFromTFT(0, 6); - SquelchSprite.copyFontFromTFT(0, 0); - } else { - if (menu) PSSprite.setTextFont(0); else PSSprite.setTextFont(2); - OneBigLineSprite.copyFontFromTFT(3, 0); - FullLineSprite.copyFontFromTFT(2, 0); - GeneralTextSprite.copyFontFromTFT(2, 0); - GeneralTextSprite.copyFontFromTFT(3, 1); - FrequencySprite.copyFontFromTFT(2, 6); - SquelchSprite.copyFontFromTFT(2, 0); - } -} - -uint8_t doAutoMemory(uint16_t startfreq, uint16_t stopfreq, uint8_t startmem, uint8_t stopmem, bool rdsonly, uint8_t doublepi) { - uint8_t error = 0; - uint8_t counter = 0; - uint8_t rangestart = startmem; - uint16_t _current = frequency; - uint16_t totalIterations = (stopfreq - startfreq) + 1; - uint16_t currentIteration = 0; - uint8_t percent = 0; - uint8_t percentold = 0; - bool stopScanning = false; - bool dostore = false; - - radio.setMute(); - radio.power(0); - band = BAND_FM; - tunemode = TUNE_MAN; - - tft.drawRect(59, 109, 202, 8, FrameColor); - tft.fillRect(60, 110, 200, 6, GreyoutColor); - tftPrint(ARIGHT, textUI(268), 120, 155, ActiveColor, ActiveColorSmooth, 16); - - for (frequency = startfreq * 10; frequency <= stopfreq * 10; frequency += 10) { - if (stopScanning) break; - - currentIteration++; - percent = (currentIteration * 100) / totalIterations; - - radio.SetFreq(frequency); - radio.clearRDS(); - delay(DELAY_TUNE_MS); - radio.getStatus(&SStatus, &USN, &WAM, &OStatus, &BW, &MStatus, &CN); - if (isSignalQualityGood(USN, WAM, OStatus)) { - for (byte y = 0; y < 20; y++) { - delay(DELAY_RDS_READ_MS); - radio.readRDS(showrdserrors); - } - - dostore = true; - if (doublepi != 0) { - for (byte x = (doublepi == 1 ? rangestart : 0); x <= (doublepi == 1 ? stopmem : EE_PRESETS_CNT - 1); x++) { - if (presets[x].RDSPI[0] != '\0') { - bool allMatch = true; - - for (byte i = 0; i < 4; i++) { - if (presets[x].RDSPI[i] != radio.rds.picode[i]) { - allMatch = false; - break; - } - } - - if (allMatch) { - dostore = false; - break; - } - } - } - } - - if (((rdsonly && radio.rds.hasRDS) || !rdsonly) && dostore) { - StoreMemoryPos(startmem); - counter ++; - startmem++; - if (startmem > stopmem) { - error = 1; - stopScanning = true; - break; - } - dostore = false; - } - } - - if (percent != percentold) { - switch (CurrentTheme) { - case 7: - SignalSprite.pushImage(-107, -95, 292, 170, popupbackground_wo); - SquelchSprite.pushImage(-177, -135, 292, 170, popupbackground_wo); - break; - default: - SignalSprite.pushImage(-107, -95, 292, 170, popupbackground); - SquelchSprite.pushImage(-177, -135, 292, 170, popupbackground); - break; - } - - SignalSprite.setTextColor(SecondaryColor, SecondaryColorSmooth, false); - SignalSprite.setTextDatum(TC_DATUM); - SignalSprite.drawString(String(percent) + "%", 40, 0); - SignalSprite.pushSprite(120, 125); - - SquelchSprite.setTextColor(PrimaryColor, PrimaryColorSmooth, false); - SquelchSprite.drawString(String(counter), 0, 0); - SquelchSprite.pushSprite(200, 155); - - tft.fillRect(60, 110, 2 * percent, 6, BarInsignificantColor); - - percentold = percent; - } - if (digitalRead(MODEBUTTON) == LOW) { - while (digitalRead(MODEBUTTON)) delay(50); - error = 2; - stopScanning = true; - break; - } - } - - frequency = _current; - radio.SetFreq(frequency); - radio.clearRDS(); - radio.setUnMute(); - SQ = false; - - return error; -} +} \ No newline at end of file diff --git a/src/nonvolatile.cpp b/src/nonvolatile.cpp index 54cb3e7..c4e7657 100644 --- a/src/nonvolatile.cpp +++ b/src/nonvolatile.cpp @@ -247,7 +247,7 @@ void DefaultSettings() { EEPROM.writeUInt(EE_UINT16_CONVERTERSET, 0); EEPROM.writeUInt(EE_UINT16_FMLOWEDGESET, 875); EEPROM.writeUInt(EE_UINT16_FMHIGHEDGESET, 1080); - EEPROM.writeByte(EE_BYTE_CONTRASTSET, 20); + EEPROM.writeByte(EE_BYTE_CONTRASTSET, 10); EEPROM.writeByte(EE_BYTE_STEREOLEVEL, 0); EEPROM.writeByte(EE_BYTE_BANDFM, FM_BAND_ALL); EEPROM.writeByte(EE_BYTE_BANDAM, AM_BAND_ALL); @@ -257,7 +257,7 @@ void DefaultSettings() { EEPROM.writeByte(EE_BYTE_RTBUFFER, 0); EEPROM.writeByte(EE_BYTE_EDGEBEEP, 0); EEPROM.writeByte(EE_BYTE_SOFTMUTEAM, 1); - EEPROM.writeByte(EE_BYTE_SOFTMUTEFM, 0); + EEPROM.writeByte(EE_BYTE_SOFTMUTEFM, 1); EEPROM.writeUInt(EE_UINT16_FREQUENCY_AM, 828); EEPROM.writeByte(EE_BYTE_LANGUAGE, 0); EEPROM.writeByte(EE_BYTE_SHOWRDSERRORS, 0); diff --git a/src/rds.cpp b/src/rds.cpp index 86f1b45..d1c481e 100644 --- a/src/rds.cpp +++ b/src/rds.cpp @@ -66,7 +66,7 @@ void ShowAdvancedRDS() { } if(!screenmute) { uint8_t font = 0; - if(radio.rds.ECC.get() == 190) font = 1; + if(radio.rds.ECC.get() == 190) font = 1; // Chiba (Chiba) else if(radio.rds.ECC.get() == 192) font = 1; else if(radio.rds.ECC.get() == 201) font = 1; eccDisplay.update(ECCString, RDSstatus, RDSColor, RDSColorSmooth, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, font); @@ -187,7 +187,7 @@ void readRds() { if (!rdsstatscreen) { if (radio.rds.region == 0) tftPrint(ACENTER, PIold, 275, advancedRDS ? 75 : 187, RDSColor, RDSColorSmooth, 28); else { - tftPrint(ALEFT, PIold, 240, advancedRDS ? 72 : 184, RDSColor, RDSColorSmooth, 16); + tftPrint16(ALEFT, PIold, 240, advancedRDS ? 72 : 184, RDSColor, RDSColorSmooth); tftPrint(ALEFT, stationIDold, 240, advancedRDS ? 89 : 201, RDSColor, RDSColorSmooth, 16); tftPrint( 1, stationStateold, 318, advancedRDS ? 89 : 201, advancedRDS ? RDSColor : RDSDropoutColor, advancedRDS ? RDSColorSmooth : RDSDropoutColorSmooth, 16); } @@ -203,8 +203,7 @@ void readRds() { } else { PSSprite.setTextColor(RDSColor, RDSColorSmooth, false); PSSprite.drawString(PSold, 0, 2); - } - PSSprite.pushSprite(36, advancedRDS ? 72 : 185); + } PSSprite.pushSprite(36, advancedRDS ? 72 : 185); } tft.fillCircle(314, 223, 2, GreyoutColor); @@ -248,9 +247,9 @@ void readRds() { sprintf(hexbuf, "%04X", radio.rds.rdsD); XDRGTKRDS += hexbuf; uint8_t erroutput = 0; - erroutput |= ((radio.rds.rdsErr >> 8) & B00110000) >> 4; - erroutput |= ((radio.rds.rdsErr >> 8) & B00001100); - erroutput |= ((radio.rds.rdsErr >> 8) & B00000011) << 4; + erroutput |= ((radio.rds.rdsErr >> 8) & 0x30) >> 4; + erroutput |= ((radio.rds.rdsErr >> 8) & 0xC); + erroutput |= ((radio.rds.rdsErr >> 8) & 3) << 4; sprintf(hexbuf, "%X%X", (erroutput >> 4) & 0xF, erroutput & 0xF); XDRGTKRDS += hexbuf; @@ -366,15 +365,14 @@ void showPI() { else tftReplace(ACENTER, PIold, radio.rds.picode, 275, 75, RDSColor, RDSColorSmooth, BackgroundColor, 28); } else { if (!RDSstatus) { - if (String(radio.rds.picode) != PIold) tftReplace(ALEFT, PIold, radio.rds.picode, 240, 72, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16); + if (String(radio.rds.picode) != PIold) tftReplace16(ALEFT, PIold, radio.rds.picode, 240, 72, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor); tftReplace(ALEFT, stationIDold, radio.rds.stationIDtext, 240, 89, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16); } else { - if (String(radio.rds.picode) != PIold) tftReplace(ALEFT, PIold, radio.rds.picode, 240, 72, RDSColor, RDSColorSmooth, BackgroundColor, 16); + if (String(radio.rds.picode) != PIold) tftReplace16(ALEFT, PIold, radio.rds.picode, 240, 72, RDSColor, RDSColorSmooth, BackgroundColor); tftReplace(ALEFT, stationIDold, radio.rds.stationIDtext, 240, 89, RDSColor, RDSColorSmooth, BackgroundColor, 16); - } - tftReplace(ARIGHT, stationStateold, radio.rds.stationStatetext, 318, 89, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16); + } tftReplace(ARIGHT, stationStateold, radio.rds.stationStatetext, 318, 89, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16); } - } else if (afscreen) tftReplace(ALEFT, PIold, radio.rds.picode, 30, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor, 16); + } else if (afscreen) tftReplace16(ALEFT, PIold, radio.rds.picode, 30, 201, BWAutoColor, BWAutoColorSmooth, BackgroundColor); else if (!rdsstatscreen) { if (radio.rds.region == 0) { if (!RDSstatus) tftReplace(ACENTER, PIold, radio.rds.picode, 275, 187, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 28); @@ -382,12 +380,12 @@ void showPI() { } else { if (!RDSstatus) { if (String(radio.rds.picode) != PIold || radio.rds.stationIDtext != stationIDold) { - tftReplace(ALEFT, PIold, radio.rds.picode, 240, 184, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16); + tftReplace16(ALEFT, PIold, radio.rds.picode, 240, 184, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor); tftReplace(ALEFT, stationIDold, radio.rds.stationIDtext, 240, 201, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16); } } else { if (String(radio.rds.picode) != PIold || radio.rds.stationIDtext != stationIDold) { - tftReplace(ALEFT, PIold, radio.rds.picode, 240, 184, RDSColor, RDSColorSmooth, BackgroundColor, 16); + tftReplace16(ALEFT, PIold, radio.rds.picode, 240, 184, RDSColor, RDSColorSmooth, BackgroundColor); tftReplace(ALEFT, stationIDold, radio.rds.stationIDtext, 240, 201, RDSColor, RDSColorSmooth, BackgroundColor, 16); tftReplace(ARIGHT, stationStateold, radio.rds.stationStatetext, 318, 201, RDSDropoutColor, RDSDropoutColorSmooth, BackgroundColor, 16); } @@ -523,8 +521,8 @@ void showCT() { rds_date = String(dateStr); if (!screenmute && showclock && (rds_clock != rds_clockold || rds_date != rds_dateold || radio.rds.hasCT.changed(0))) { - tftReplace(ACENTER, rds_clockold, rds_clock, 134, 1, RDSColor, RDSColorSmooth, BackgroundColor, 16); - tftReplace(ACENTER, rds_dateold, rds_date, 134, 15, RDSColor, RDSColorSmooth, BackgroundColor, 16); + tftReplace16(ACENTER, rds_clockold, rds_clock, 134, 1, RDSColor, RDSColorSmooth, BackgroundColor); + tftReplace16(ACENTER, rds_dateold, rds_date, 134, 15, RDSColor, RDSColorSmooth, BackgroundColor); rds_clockold = rds_clock; rds_dateold = rds_date; } @@ -573,7 +571,7 @@ void ShowAFEON() { if (radio.rds.hasAF && afpagenr == 1) { if (!hasafold) { tftPrint(ALEFT, textUI(84), 6, 48, BackgroundColor, BackgroundColor, 16); - tftPrint(ALEFT, "AF:", 4, 32, ActiveColor, ActiveColorSmooth, 16); + tftPrint16(ALEFT, "AF:", 4, 32, ActiveColor, ActiveColorSmooth); hasafold = true; } @@ -596,10 +594,10 @@ void ShowAFEON() { if (radio.eon_counter > 0 && afpagenr > 1) { if (!haseonold) { tftPrint(ALEFT, textUI(85), 6, 48, BackgroundColor, BackgroundColor, 16); - tftPrint(ALEFT, "PI", 4, 32, ActiveColor, ActiveColorSmooth, 16); - tftPrint(ACENTER, "TA", 250, 32, ActiveColor, ActiveColorSmooth, 16); - tftPrint(ACENTER, "TP", 276, 32, ActiveColor, ActiveColorSmooth, 16); - tftPrint(ACENTER, "PTY", 304, 32, ActiveColor, ActiveColorSmooth, 16); + tftPrint16(ALEFT, "PI", 4, 32, ActiveColor, ActiveColorSmooth); + tftPrint16(ACENTER, "TA", 250, 32, ActiveColor, ActiveColorSmooth); + tftPrint16(ACENTER, "TP", 276, 32, ActiveColor, ActiveColorSmooth); + tftPrint16(ACENTER, "PTY", 304, 32, ActiveColor, ActiveColorSmooth); haseonold = true; } @@ -626,7 +624,7 @@ void ShowAFEON() { strcpy(eonpicodeold[i + y], radio.eon[i + y].picode); if (radio.eon[i + y].ps.length() > 0) { - tftPrint(ALEFT, "PS", 46, 32, ActiveColor, ActiveColorSmooth, 16); + tftPrint16(ALEFT, "PS", 46, 32, ActiveColor, ActiveColorSmooth); if (strcmp(radio.eon[i + y].ps.c_str(), eonpsold[i + y].c_str()) != 0) tftPrint(ALEFT, eonpsold[i + y].c_str(), 46, 48 + (15 * i), BackgroundColor, BackgroundColor, 16); tftPrint(ALEFT, radio.eon[i + y].ps.c_str(), 46, 48 + (15 * i), RDSDropoutColor, RDSDropoutColorSmooth, 16); @@ -771,7 +769,7 @@ void ShowRDSStatistics() { xposPct = 310; } - uint8_t row = rb & 0x07; + uint8_t row = rb & 0x07; uint8_t ypos = pgm_read_byte(&rdsYpos[row]); static int16_t lastX = -1, lastY = -1; @@ -814,7 +812,7 @@ void ShowRDSStatistics() { } if (radio.processed_rdsblocks > 0 && !dropout) { - const uint8_t xErr[4] = {86, 124, 162, 200}; + constexpr uint8_t xErr[4] = {86, 124, 162, 200}; const bool errors[4] = {radio.rds.rdsAerror, radio.rds.rdsBerror, radio.rds.rdsCerror, radio.rds.rdsDerror}; for (uint8_t i = 0; i < 4; i++) tft.fillCircle(xErr[i], 41, 5, errors[i] ? SignificantColor : InsignificantColor); @@ -824,17 +822,17 @@ void ShowRDSStatistics() { int errC = ((radio.rds.rdsErr >> 8) & 12) >> 2; int errD = (radio.rds.rdsErr & 3); - const int weights[4] = {0, 2, 6, 12}; + constexpr int weights[4] = {0, 2, 6, 12}; int errorBits = weights[errA] + weights[errB] + weights[errC] + weights[errD]; - int totalBits = 4 * 26; + constexpr int totalBits = 4 * 26; float ber = (float)errorBits / (float)totalBits; ber = sqrt(ber); if (ber > 1.0) ber = 1.0; - float alpha = 0.05; + constexpr float alpha = 0.05; smoothBER = (1.0 - alpha) * smoothBER + alpha * ber; int berPercent = (int)(smoothBER * 100.0); diff --git a/src/utils.cpp b/src/utils.cpp index 4fcc655..10ece1d 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -96,8 +96,7 @@ String ucs2ToUtf8(const char* ucs2Input) { utf8Output += (char)(0x80 | ((ucs2Char >> 6) & 0x3F)); utf8Output += (char)(0x80 | (ucs2Char & 0x3F)); } - } - return utf8Output; + } return utf8Output; } String extractUTF8Substring(const String & utf8String, size_t start, size_t length, bool underscore) { @@ -133,6 +132,5 @@ String removeNewline(String inputString) { for (int i = 0; i < inputString.length(); i++) { if (inputString[i] == '\n') outputString += ' '; else outputString += inputString[i]; - } - return outputString; + } return outputString; } \ No newline at end of file