SI4684-DAB-Receiver/SI4684-DAB-Receiver.ino

1013 wiersze
28 KiB
C++

#include <TFT_eSPI.h>
#include <LittleFS.h>
#include <TimeLib.h>
#include "soc/soc.h"
#include "soc/rtc_cntl_reg.h"
#include <EEPROM.h>
#include <Wire.h>
#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();
}
}