#include #include #include #include "soc/soc.h" #include "soc/rtc_cntl_reg.h" #include #include #include "src/font.h" #include "src/constants.h" #include "src/graphics.h" #include "src/language.h" #include "src/gui.h" #include "src/comms.h" #include "src/slideshow.h" #include "src/si4684.h" #include "src/TPA6130A2.h" TPA6130A2 Headphones; DAB radio; TFT_eSPI tft = TFT_eSPI(240, 320); bool autoslideshow; bool ChannelListView; bool direction; bool displayreset; bool memorystore; bool menu; bool menuopen; bool resetFontOnNextCall; bool seek; bool setupmode; bool setvolume; bool ShowServiceInformation; bool SlideShowAvailableOld; bool SlideShowView; bool store; bool trysetservice; bool tuned; bool tuning; byte audiomodeold; byte ContrastSet; byte CurrentTheme; byte dabfreq; byte dabfreqold; byte displayflip; byte eccold; byte ficold; byte language; byte memorypos; byte memoryposold; byte memoryposstatus; byte ptyold; byte rotarymode; byte servicetypeold; byte subnetclient; byte tot; byte tunemode; byte unit; byte volume; char _serviceName[17]; const uint8_t* currentFont = nullptr; int ActiveColor; int ActiveColorSmooth; int BackgroundColor; int BackgroundColor2; int BackgroundColor3; int BackgroundColor4; int BarInsignificantColor; int BarSignificantColor; int Bitrateupdatetimer; int GreyoutColor; int InsignificantColor; int InsignificantColorSmooth; int menuoption = ITEM1; int PrimaryColor; int PrimaryColorSmooth; int rotary; int rotary2; int rssi; int rssiold = 200; int RTlengthold; int RTWidth; int SecondaryColor; int SecondaryColorSmooth; int SignalLevelold; int SignificantColor; int SignificantColorSmooth; int SNRupdatetimer; int xPos; int16_t SAvg; int16_t SAvg2; int16_t SignalLevel; int8_t CNR; int8_t CNRold; String clockstringOld; String datestringOld; String EIDold; String EnsembleNameOld; String dabfreqStringOld; String ITUold; String PLold; String PSold; String RTold; String SIDold; String SignalLeveloldString; uint16_t BitrateOld; uint32_t _serviceID; uint8_t freq = 0; uint8_t service = 0; unsigned long tottimer; unsigned long rssiTimer; unsigned long rtticker; unsigned long rttickerhold; unsigned long TuningTimer; unsigned long VolumeTimer; static const int8_t enc_states[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; typedef struct _Memory { byte Channel; uint32_t ServiceID; char Label[17]; } DABMemory; TFT_eSprite FullLineSprite = TFT_eSprite(&tft); TFT_eSprite OneBigLineSprite = TFT_eSprite(&tft); TFT_eSprite LongSprite = TFT_eSprite(&tft); TFT_eSprite MediumSprite = TFT_eSprite(&tft); TFT_eSprite ModeSprite = TFT_eSprite(&tft); TFT_eSprite ShortSprite = TFT_eSprite(&tft); DABMemory memory[EE_PRESETS_CNT]; void setup(void) { WRITE_PERI_REG(RTC_CNTL_BROWN_OUT_REG, 0); gpio_set_drive_capability((gpio_num_t) 4, GPIO_DRIVE_CAP_0); gpio_set_drive_capability((gpio_num_t) 5, GPIO_DRIVE_CAP_0); gpio_set_drive_capability((gpio_num_t) 13, GPIO_DRIVE_CAP_0); gpio_set_drive_capability((gpio_num_t) 14, GPIO_DRIVE_CAP_0); gpio_set_drive_capability((gpio_num_t) 15, 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) 21, GPIO_DRIVE_CAP_0); gpio_set_drive_capability((gpio_num_t) 22, GPIO_DRIVE_CAP_0); setupmode = true; LittleFS.begin(); LittleFS.format(); Serial.begin(1000000); EEPROM.begin(EE_TOTAL_CNT); if (EEPROM.readByte(EE_BYTE_CHECKBYTE) != EE_CHECKBYTE_VALUE) DefaultSettings(); ContrastSet = EEPROM.readByte(EE_BYTE_CONTRASTSET); language = EEPROM.readByte(EE_BYTE_LANGUAGE); displayflip = EEPROM.readByte(EE_BYTE_DISPLAYFLIP); rotarymode = EEPROM.readByte(EE_BYTE_ROTARYMODE); tunemode = EEPROM.readByte(EE_BYTE_TUNEMODE); unit = EEPROM.readByte(EE_BYTE_UNIT); dabfreq = EEPROM.readByte(EE_BYTE_DABFREQ); volume = EEPROM.readByte(EE_BYTE_VOLUME); memorypos = EEPROM.readByte(EE_BYTE_MEMORYPOS); autoslideshow = EEPROM.readByte(EE_BYTE_AUTOSLIDESHOW); tot = EEPROM.readByte(EE_BYTE_TOT); CurrentTheme = EEPROM.readByte(EE_BYTE_THEME); radio.BufferSlideShow = EEPROM.readByte(EE_BYTE_BUFFERSLIDESHOW); for (int i = 0; i < EE_PRESETS_CNT; i++) { memory[i].Channel = EEPROM.readByte(i + EE_PRESETS_FREQ_START); EEPROM.get((i * 8) + EE_PRESETS_SERVICEID_START, memory[i].ServiceID); for (int y = 0; y < 16; y++) { memory[i].Label[y] = EEPROM.readByte((i * 17) + y + EE_PRESETS_NAME_START); } memory[i].Label[16] = '\0'; } Headphones.Init(); delay(50); Headphones.SetHiZ(0); delay(50); Headphones.SetVolume(volume); tft.init(); tft.initDMA(); doTheme(); if (displayflip == 0) tft.setRotation(3); else tft.setRotation(1); pinMode(STANDBYBUTTON, INPUT); pinMode(MODEBUTTON, INPUT); pinMode(SLBUTTON, INPUT); pinMode(ROTARY_BUTTON, INPUT); pinMode(ROTARY_BUTTON2, INPUT); pinMode(ROTARY_PIN_A, INPUT); pinMode(ROTARY_PIN_B, INPUT); pinMode(ROTARY_PIN_2A, INPUT); pinMode(ROTARY_PIN_2B, INPUT); attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_A), read_encoder, CHANGE); attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_B), read_encoder, CHANGE); attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_2A), read_encoder2, CHANGE); attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_2B), read_encoder2, CHANGE); tft.setSwapBytes(true); tft.fillScreen(BackgroundColor); OneBigLineSprite.createSprite(270, 30); OneBigLineSprite.setSwapBytes(true); ShortSprite.createSprite(36, 16); ShortSprite.setSwapBytes(true); MediumSprite.createSprite(70, 16); MediumSprite.setSwapBytes(true); LongSprite.createSprite(150, 17); LongSprite.setSwapBytes(true); FullLineSprite.createSprite(308, 20); FullLineSprite.setSwapBytes(true); ModeSprite.createSprite(46, 47); ModeSprite.setTextDatum(TC_DATUM); ModeSprite.setSwapBytes(true); loadFonts(true); if (digitalRead(SLBUTTON) == LOW && digitalRead(ROTARY_BUTTON) == HIGH) { if (rotarymode == 0) rotarymode = 1; else rotarymode = 0; EEPROM.writeByte(EE_BYTE_ROTARYMODE, rotarymode); EEPROM.commit(); analogWrite(CONTRASTPIN, ContrastSet * 2 + 27); tftPrint(0, myLanguage[language][1], 155, 70, ActiveColor, ActiveColorSmooth, 28); tftPrint(0, myLanguage[language][2], 155, 130, ActiveColor, ActiveColorSmooth, 28); while (digitalRead(SLBUTTON) == LOW); } if (digitalRead(MODEBUTTON) == LOW) { if (displayflip == 0) { displayflip = 1; tft.setRotation(1); } else { displayflip = 0; tft.setRotation(3); } EEPROM.writeByte(EE_BYTE_DISPLAYFLIP, displayflip); EEPROM.commit(); analogWrite(CONTRASTPIN, ContrastSet * 2 + 27); tftPrint(0, myLanguage[language][3], 155, 70, ActiveColor, ActiveColorSmooth, 28); tftPrint(0, myLanguage[language][2], 155, 130, ActiveColor, ActiveColorSmooth, 28); while (digitalRead(MODEBUTTON) == LOW); } if (digitalRead(ROTARY_BUTTON) == LOW && digitalRead(SLBUTTON) == LOW) { DefaultSettings(); analogWrite(CONTRASTPIN, ContrastSet * 2 + 27); tftPrint(0, myLanguage[language][10], 155, 70, ActiveColor, ActiveColorSmooth, 28); tftPrint(0, myLanguage[language][2], 155, 130, ActiveColor, ActiveColorSmooth, 28); while (digitalRead(ROTARY_BUTTON) == LOW && digitalRead(SLBUTTON) == LOW); ESP.restart(); } tft.pushImage (0, 0, 320, 240, SplashScreen); tftPrint(0, myLanguage[language][72], 155, 15, ActiveColor, ActiveColorSmooth, 28); tftPrint(0, String(myLanguage[language][9]) + " " + String(VERSION), 160, 190, TFT_WHITE, TFT_DARKGREY, 16); for (int x = 0; x <= ContrastSet; x++) { analogWrite(CONTRASTPIN, x * 2 + 27); delay(30); } if (radio.begin(15)) { tftPrint(0, String(radio.getChipID()) + " v" + String(radio.getFirmwareVersion()), 160, 210, TFT_WHITE, TFT_DARKGREY, 16); } else { tftPrint(0, myLanguage[language][77], 160, 210, TFT_WHITE, TFT_DARKGREY, 16); for (;;); } delay(1500); if (tunemode == TUNE_MEM && !IsStationEmpty()) { DoMemoryPosTune(); } else { if (tunemode == TUNE_MEM) tunemode = TUNE_MAN; radio.setFreq(dabfreq); EEPROM.get(EE_UINT32_SERVICEID, _serviceID); for (int i = 0; i < 16; i++) { _serviceName[i] = EEPROM.readByte(i + EE_CHAR17_SERVICENAME); } } if (_serviceID != 0 ) trysetservice = true; BuildDisplay(); setupmode = false; tottimer = millis(); } void loop(void) { ProcessDAB(); Communication(); displayreset = false; if (seek) Seek(direction); if (tot != 0) { unsigned long totprobe = tot * 60000; if (millis() >= tottimer + totprobe) deepSleep(); } if (millis() >= TuningTimer + 500) { if (store) { detachInterrupt(digitalPinToInterrupt(ROTARY_PIN_A)); detachInterrupt(digitalPinToInterrupt(ROTARY_PIN_B)); StoreFrequency(); store = false; attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_A), read_encoder, CHANGE); attachInterrupt(digitalPinToInterrupt(ROTARY_PIN_B), read_encoder, CHANGE); } else if (tuning) { radio.setFreq(dabfreq); tuning = false; if (tunemode == TUNE_MEM) trysetservice = true; } } if (millis() >= VolumeTimer + 3000 && setvolume) { closeVolume(); } if (!menu) { if (rotary2 == -1) KeyUp2(); if (rotary2 == 1) KeyDown2(); } if (rotary == -1) KeyUp(); if (rotary == 1) KeyDown(); if (digitalRead(MODEBUTTON) == LOW) ModeButtonPress(); if (!menu && digitalRead(SLBUTTON) == LOW) SlideShowButtonPress(); if (!menu && digitalRead(STANDBYBUTTON) == LOW) StandbyButtonPress(); if (digitalRead(ROTARY_BUTTON) == LOW) ButtonPress(); if (!menu && digitalRead(ROTARY_BUTTON2) == LOW) Button2Press(); } void ProcessDAB(void) { if (!tuning) { radio.Update(); SignalLevel = radio.getRSSI(); } if (radio.panic()) doRecovery(); if (trysetservice && radio.signallock) { for (byte x = 0; x < radio.numberofservices; x++) { if (_serviceID == radio.service[x].ServiceID) { radio.setService(x); radio.ServiceStart = true; trysetservice = false; store = true; } } } if (!SlideShowView && !menu) { if (!ChannelListView) ShowSignalLevel(); ShowRT(); if (!ShowServiceInformation && !ChannelListView) { if (autoslideshow && radio.SlideShowAvailable && radio.SlideShowUpdate) { SlideShowButtonPress(); } else { ShowBitrate(); ShowEID(); ShowSID(); ShowPTY(); ShowProtectionlevel(); ShowPS(); ShowEN(); ShowAudioMode(); ShowClock(); ShowSlideShowIcon(); ShowECC(); } } } else { if (radio.SlideShowAvailable && radio.SlideShowUpdate && !menu) { ShowSlideShow(); radio.SlideShowUpdate = false; } } } void closeVolume(void) { if (ChannelListView) { BuildChannelList(); } else if (ShowServiceInformation) { ShowServiceInfo(); } else if (SlideShowView) { SlideShowView = false; SlideShowButtonPress(); } else { BuildDisplay(); } } void doRecovery(void) { radio.begin(15); radio.setFreq(dabfreq); trysetservice = true; } void DABSelectService(bool dir) { if (radio.numberofservices > 0) { bool hasValidService = false; for (int i = 0; i < radio.numberofservices; i++) { if (radio.service[i].ServiceType == 0x00 || radio.service[i].ServiceType == 0x04 || radio.service[i].ServiceType == 0x05) { hasValidService = true; break; } } if (!hasValidService) return; if (dir) { radio.ServiceIndex = (radio.ServiceIndex + 1) % radio.numberofservices; } else { radio.ServiceIndex = (radio.ServiceIndex == 0) ? (radio.numberofservices - 1) : (radio.ServiceIndex - 1); } while (radio.service[radio.ServiceIndex].ServiceType != 0x00 && radio.service[radio.ServiceIndex].ServiceType != 0x04 && radio.service[radio.ServiceIndex].ServiceType != 0x05) { if (dir) { radio.ServiceIndex = (radio.ServiceIndex + 1) % radio.numberofservices; } else { radio.ServiceIndex = (radio.ServiceIndex == 0) ? (radio.numberofservices - 1) : (radio.ServiceIndex - 1); } } radio.setService(radio.ServiceIndex); radio.ServiceStart = true; store = true; } } void StoreFrequency(void) { EEPROM.put(EE_UINT32_SERVICEID, radio.service[radio.ServiceIndex].ServiceID); EEPROM.put(EE_BYTE_DABFREQ, dabfreq); for (int i = 0; i < 16; i++) { EEPROM.writeByte(i + EE_CHAR17_SERVICENAME, radio.PStext[i]); } EEPROM.commit(); _serviceID = radio.service[radio.ServiceIndex].ServiceID; } void ButtonPress(void) { tottimer = millis(); if (!menu) { if (tunemode == TUNE_MEM) { if (!memorystore) { memorystore = true; if (!IsStationEmpty()) memoryposstatus = MEM_EXIST; else memoryposstatus = MEM_NORMAL; ShowMemoryPos(); ShowTuneMode(); } else { memorystore = false; EEPROM.writeByte(memorypos + EE_PRESETS_FREQ_START, dabfreq); EEPROM.put((memorypos * 8) + EE_PRESETS_SERVICEID_START, radio.service[radio.ServiceIndex].ServiceID); for (int x = 0; x < 16; x++) { char character = radio.service[radio.ServiceIndex].Label[x]; EEPROM.writeByte((memorypos * 17) + x + EE_PRESETS_NAME_START, character); memory[memorypos].Label[x] = character; } EEPROM.writeByte((memorypos * 17) + 16 + EE_PRESETS_NAME_START, '\0'); memory[memorypos].Label[16] = '\0'; memory[memorypos].Channel = dabfreq; memory[memorypos].ServiceID = radio.service[radio.ServiceIndex].ServiceID; EEPROM.commit(); ShowTuneMode(); if (memoryposstatus == MEM_DARK || memoryposstatus == MEM_EXIST) { memoryposstatus = MEM_NORMAL; ShowMemoryPos(); } } } else { if (ChannelListView || SlideShowView || ShowServiceInformation) { BuildDisplay(); } else { ChannelListView = true; BuildChannelList(); } } } else { DoMenu(); } while (digitalRead(ROTARY_BUTTON) == LOW); } void Button2Press(void) { memorystore = false; memoryposstatus = MEM_NORMAL; tottimer = millis(); if (setvolume) { closeVolume(); } else { setvolume = true; ShowVolume(); } while (digitalRead(ROTARY_BUTTON2) == LOW); } void SlideShowButtonPress(void) { setvolume = false; memorystore = false; memoryposstatus = MEM_NORMAL; if (!SlideShowView && radio.SlideShowAvailable) { tft.fillScreen(TFT_BLACK); radio.SlideShowUpdate = true; SlideShowView = true; ShowServiceInformation = false; } else { if (SlideShowView) BuildDisplay(); SlideShowView = false; } while (digitalRead(SLBUTTON) == LOW); } void ModeButtonPress(void) { tottimer = millis(); seek = false; unsigned long counterold = millis(); unsigned long counter = millis(); while (digitalRead(MODEBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); if (menu) { EEPROM.writeByte(EE_BYTE_LANGUAGE, language); EEPROM.writeByte(EE_BYTE_CONTRASTSET, ContrastSet); EEPROM.writeByte(EE_BYTE_AUTOSLIDESHOW, autoslideshow); EEPROM.writeByte(EE_BYTE_UNIT, unit); EEPROM.writeByte(EE_BYTE_TOT, tot); EEPROM.writeByte(EE_BYTE_THEME, CurrentTheme); EEPROM.writeByte(EE_BYTE_BUFFERSLIDESHOW, radio.BufferSlideShow); EEPROM.commit(); menu = false; BuildDisplay(); } else if (SlideShowView || ChannelListView || ShowServiceInformation) { BuildDisplay(); } else { memorystore = false; memoryposstatus = MEM_NORMAL; if (counter - counterold <= 1000) { tunemode++; if (tunemode > 2) tunemode = 0; ShowTuneMode(); ShowMemoryPos(); } else { menu = true; BuildMenu(); } } while (digitalRead(MODEBUTTON) == LOW); } void StandbyButtonPress(void) { tottimer = millis(); unsigned long counterold = millis(); unsigned long counter = millis(); if (memorystore) { EEPROM.writeByte(memorypos + EE_PRESETS_FREQ_START, EE_PRESETS_FREQUENCY); EEPROM.put((memorypos * 8) + EE_PRESETS_SERVICEID_START, 0); for (int x = 0; x < 16; x++) { EEPROM.writeByte((memorypos * 17) + x + EE_PRESETS_NAME_START, '\0'); memory[memorypos].Label[x] = '\0'; } EEPROM.writeByte((memorypos * 17) + 16 + EE_PRESETS_NAME_START, '\0'); memory[memorypos].Label[16] = '\0'; memory[memorypos].Channel = EE_PRESETS_FREQUENCY; memory[memorypos].ServiceID = 0; EEPROM.commit(); memorystore = false; ShowTuneMode(); if (memoryposstatus == MEM_DARK || memoryposstatus == MEM_EXIST) { memoryposstatus = MEM_NORMAL; ShowMemoryPos(); } } else { while (digitalRead(STANDBYBUTTON) == LOW && counter - counterold <= 1000) counter = millis(); if (counter - counterold <= 1000) { if (!ShowServiceInformation && !SlideShowView && !ChannelListView) { ShowServiceInfo(); ShowServiceInformation = true; } else { BuildDisplay(); } } else { doStandby(); } } while (digitalRead(STANDBYBUTTON) == LOW); } void KeyUp(void) { if (setvolume) closeVolume(); tottimer = millis(); rotary = 0; rotary2 = 0; if (SlideShowView) SlideShowButtonPress(); if (!menu) { if (!ChannelListView) { if (ShowServiceInformation) BuildDisplay(); switch (tunemode) { case TUNE_MAN: dabfreq++; if (dabfreq > 37) dabfreq = 0; tuning = true; TuningTimer = millis(); radio.ServiceIndex = 0; radio.ServiceStart = false; radio.clearData(); for (byte x = 0; x < 17; x++) _serviceName[x] = '\0'; ShowFreq(); break; case TUNE_AUTO: radio.ServiceIndex = 0; radio.ServiceStart = false; radio.clearData(); direction = true; seek = true; 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_NORMAL; } ShowMemoryPos(); break; } } else { byte y = 0; byte y_old = 0; if (radio.ServiceIndex > 8 && radio.ServiceIndex < 17) { y_old = 9; } else if (radio.ServiceIndex > 16 && radio.ServiceIndex < 25) { y_old = 17; } else if (radio.ServiceIndex > 24) { y_old = 25; } ShowOneLine(20 * (radio.ServiceIndex - y_old), radio.ServiceIndex, false); if (radio.numberofservices > 0) DABSelectService(1); if (radio.ServiceIndex > 8 && radio.ServiceIndex < 17) { y = 9; } else if (radio.ServiceIndex > 16 && radio.ServiceIndex < 25) { y = 17; } else if (radio.ServiceIndex > 24) { y = 25; } if (y_old != y) { BuildChannelList(); } else { ShowOneLine(20 * (radio.ServiceIndex - y), radio.ServiceIndex, true); } } } else { MenuUp(); } } void KeyDown(void) { if (setvolume) closeVolume(); tottimer = millis(); rotary = 0; rotary2 = 0; if (SlideShowView) SlideShowButtonPress(); if (!menu) { if (!ChannelListView) { if (ShowServiceInformation) BuildDisplay(); switch (tunemode) { case TUNE_MAN: dabfreq--; if (dabfreq > 37) dabfreq = 37; tuning = true; TuningTimer = millis(); radio.ServiceIndex = 0; radio.ServiceStart = false; radio.clearData(); for (byte x = 0; x < 17; x++) _serviceName[x] = '\0'; ShowFreq(); break; case TUNE_AUTO: radio.ServiceIndex = 0; radio.ServiceStart = false; radio.clearData(); direction = false; seek = true; 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_NORMAL; } ShowMemoryPos(); break; } } else { byte y = 0; byte y_old = 0; if (radio.ServiceIndex > 8 && radio.ServiceIndex < 17) { y_old = 9; } else if (radio.ServiceIndex > 16 && radio.ServiceIndex < 25) { y_old = 17; } else if (radio.ServiceIndex > 24) { y_old = 25; } ShowOneLine(20 * (radio.ServiceIndex - y_old), radio.ServiceIndex, false); if (radio.numberofservices > 0) DABSelectService(0); if (radio.ServiceIndex > 8 && radio.ServiceIndex < 17) { y = 9; } else if (radio.ServiceIndex > 16 && radio.ServiceIndex < 25) { y = 17; } else if (radio.ServiceIndex > 24) { y = 25; } if (y_old != y) { BuildChannelList(); } else { ShowOneLine(20 * (radio.ServiceIndex - y), radio.ServiceIndex, true); } } } else { MenuDown(); } } void KeyUp2(void) { tottimer = millis(); if (setvolume || tunemode == TUNE_MEM || SlideShowView || ShowServiceInformation || ChannelListView) { setvolume = true; if (volume < 62) volume += 2; ShowVolume(); } else { if (radio.numberofservices > 0) DABSelectService(1); TuningTimer = millis(); } rotary2 = 0; } void KeyDown2(void) { tottimer = millis(); rotary = 0; rotary2 = 0; if (setvolume || tunemode == TUNE_MEM || SlideShowView || ShowServiceInformation || ChannelListView) { setvolume = true; if (volume > 0) volume -= 2; ShowVolume(); } else { if (radio.numberofservices > 0) DABSelectService(0); TuningTimer = millis(); } } void DoMemoryPosTune(void) { if (IsStationEmpty()) { memoryposstatus = MEM_DARK; } else { memoryposstatus = MEM_NORMAL; dabfreq = memory[memorypos].Channel; _serviceID = memory[memorypos].ServiceID; for (int i = 0; i < 16; i++) { _serviceName[i] = memory[memorypos].Label[i]; } ShowFreq(); radio.ServiceStart = false; TuningTimer = millis(); tuning = true; } } bool IsStationEmpty(void) { if (memory[memorypos].Channel == EE_PRESETS_FREQUENCY) return true; else return false; } void doStandby(void) { tft.pushImage (0, 0, 320, 240, standbymode); tftPrint(0, myLanguage[language][78], 155, 210, ActiveColor, ActiveColorSmooth, 28); for (int x = ContrastSet; x > 0; x--) { analogWrite(CONTRASTPIN, x * 2); delay(25); } tft.writecommand(0x10); Headphones.Shutdown(); esp_sleep_enable_ext0_wakeup(GPIO_NUM_34, LOW); esp_deep_sleep_start(); } void Seek(bool mode) { if (mode) { dabfreq++; if (dabfreq > 37) dabfreq = 0; } else { dabfreq--; if (dabfreq > 37) dabfreq = 37; } radio.setFreq(dabfreq); radio.ServiceIndex = 0; radio.ServiceStart = false; ShowFreq(); radio.Update(); if (radio.signallock) seek = false; } void read_encoder(void) { static uint8_t old_AB = 3; static int8_t encval = 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 & 0x0f )]; if (encval > 3) { if (rotarymode) rotary = -1; else rotary = 1; encval = 0; } else if (encval < -3) { if (rotarymode) rotary = 1; else rotary = -1; encval = 0; } } void read_encoder2(void) { static uint8_t old_AB = 3; static int8_t encval = 0; old_AB <<= 2; if (digitalRead(ROTARY_PIN_2A)) old_AB |= 0x02; if (digitalRead(ROTARY_PIN_2B)) old_AB |= 0x01; encval += enc_states[( old_AB & 0x0f )]; if (encval > 3) { if (rotarymode) rotary2 = -1; else rotary2 = 1; encval = 0; } else if (encval < -3) { if (rotarymode) rotary2 = 1; else rotary2 = -1; encval = 0; } } void DefaultSettings(void) { EEPROM.writeByte(EE_BYTE_CHECKBYTE, EE_CHECKBYTE_VALUE); EEPROM.writeByte(EE_BYTE_CONTRASTSET, 100); EEPROM.writeByte(EE_BYTE_LANGUAGE, 0); EEPROM.writeByte(EE_BYTE_DISPLAYFLIP, 0); EEPROM.writeByte(EE_BYTE_ROTARYMODE, 0); EEPROM.writeByte(EE_BYTE_TUNEMODE, 0); EEPROM.writeByte(EE_BYTE_UNIT, 0); EEPROM.writeByte(EE_BYTE_VOLUME, 40); EEPROM.writeByte(EE_BYTE_MEMORYPOS, 0); EEPROM.writeByte(EE_BYTE_AUTOSLIDESHOW, 0); EEPROM.writeByte(EE_BYTE_BUFFERSLIDESHOW, 1); EEPROM.writeByte(EE_BYTE_TOT, 0); EEPROM.writeByte(EE_BYTE_THEME, 0); EEPROM.put(EE_UINT32_SERVICEID, 0); EEPROM.put(EE_BYTE_DABFREQ, 0); for (int y = 0; y < 17; y++) { EEPROM.writeByte(EE_CHAR17_SERVICENAME + y, '\0'); } for (int i = 0; i < EE_PRESETS_CNT; i++) { EEPROM.writeByte(i + EE_PRESETS_FREQ_START, EE_PRESETS_FREQUENCY); EEPROM.put((i * 8) + EE_PRESETS_SERVICEID_START, 0); for (int y = 0; y < 17; y++) { EEPROM.writeByte((i * 17) + y + EE_PRESETS_NAME_START, '\0'); } } EEPROM.commit(); } void tftReplace(int8_t offset, const String & textold, const String & text, int16_t x, int16_t y, int color, int smoothcolor, int backcolor, uint8_t fontsize) { const uint8_t *selectedFont = nullptr; if (fontsize == 16) selectedFont = FONT16; if (fontsize == 28) selectedFont = FONT28; if (fontsize == 52) selectedFont = FREQFONT; if (currentFont != selectedFont || resetFontOnNextCall) { if (currentFont != nullptr) tft.unloadFont(); tft.loadFont(selectedFont); currentFont = selectedFont; resetFontOnNextCall = false; } tft.setTextColor(backcolor, backcolor, false); switch (offset) { case -1: tft.setTextDatum(TL_DATUM); break; case 0: tft.setTextDatum(TC_DATUM); break; case 1: tft.setTextDatum(TR_DATUM); break; } tft.drawString(textold, x, y); tft.setTextColor(color, smoothcolor, false); 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); } void tftPrint(int8_t offset, const String & text, int16_t x, int16_t y, int color, int smoothcolor, uint8_t fontsize) { const uint8_t *selectedFont = nullptr; if (fontsize == 16) selectedFont = FONT16; if (fontsize == 28) selectedFont = FONT28; if (fontsize == 52) selectedFont = FREQFONT; if (currentFont != selectedFont || resetFontOnNextCall) { if (currentFont != nullptr) tft.unloadFont(); tft.loadFont(selectedFont); currentFont = selectedFont; resetFontOnNextCall = false; } tft.setTextColor(color, smoothcolor, (fontsize == 52 ? true : false)); 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, 1); } void deepSleep(void) { StoreFrequency(); esp_sleep_enable_ext0_wakeup(GPIO_NUM_34, LOW); esp_deep_sleep_start(); } void loadFonts(bool option) { if (option) { OneBigLineSprite.loadFont(FONT28); ShortSprite.loadFont(FONT16); MediumSprite.loadFont(FONT16); LongSprite.loadFont(FONT16); FullLineSprite.loadFont(FONT16); ModeSprite.loadFont(FONT16); } else { OneBigLineSprite.unloadFont(); ShortSprite.unloadFont(); MediumSprite.unloadFont(); LongSprite.unloadFont(); FullLineSprite.unloadFont(); ModeSprite.unloadFont(); } }