diff --git a/README.md b/README.md index 712dccc..e07cfc0 100644 --- a/README.md +++ b/README.md @@ -289,11 +289,17 @@ download _http://\/data/playlist.csv_ and _http://\/data --- ## Plugins -At the moment, you can display additional information on the display by writing a few additional functions. There is no documentation yet, you will have to deal with the example, which is in file [exsamples/displayhandlers.ino](exsamples/displayhandlers.ino).\ +At the moment, you can display additional information on the display by writing a few additional functions. There is no documentation yet, you will have to deal with the example, which is in file [exsamples/plugins/displayhandlers.ino](exsamples/plugins/displayhandlers.ino).\ Work is in progress... --- ## Version history +#### v0.6.344 +- fixed SPI-display bugs when used with VS1053B module +- added example plugin for analog volume control ([exsamples/plugins/analogvolume.ino](exsamples/plugins/analogvolume.ino)) +- added example plugin for backlight control depending on playback ([exsamples/plugins/backlightcontrols.ino](exsamples/plugins/backlightcontrols.ino)) +- added example plugin for replase a RSSI to bitrate information alternately ([exsamples/plugins/rssibitrate.ino](exsamples/plugins/rssibitrate.ino)) + #### v0.6.320 - fixed ILI9225 display bug when used with VS1053B module - fixed ILI9225 plugin support @@ -344,14 +350,14 @@ Work is in progress... #### v0.6.202 - fixed errors in the operation of the second encoder -- rewrote [plugin example](exsamples/displayhandlers.ino) +- rewrote [plugin example](exsamples/plugins/displayhandlers.ino) - fixed compilation errors on macOS #2 #### v0.6.200 - please backup your playlist and wifi settings before updating (export) - accelerated displays up to ~30fps (everything except LCD) - corrections/additions in the WEB interface (a [full update](#update) is required) -- rewrote [plugin example](exsamples/displayhandlers.ino) +- rewrote [plugin example](exsamples/plugins/displayhandlers.ino) - fixed compilation errors on macOS - changed the logic of the second encoder (switching to the volume control mode by double click) - optimization, bug fixes diff --git a/exsamples/plugins/analogvolume.ino b/exsamples/plugins/analogvolume.ino new file mode 100644 index 0000000..02c1fb0 --- /dev/null +++ b/exsamples/plugins/analogvolume.ino @@ -0,0 +1,16 @@ +/************************************************************** + + An example of volume control using an analog resistor. + This file must be in the root directory of the sketch. + +**************************************************************/ +const uint8_t volume_pin = 34; + +void ctrls_on_loop() { + static uint32_t prevVolPinMillis; + uint16_t volPinVal = map(analogRead(volume_pin), 0, 4095, 0, 254); + if((abs(volPinVal-config.store.volume)>2) && (millis()-prevVolPinMillis>300)){ /* simple debounce */ + player.setVol(volPinVal, false); + prevVolPinMillis=millis(); + } +} diff --git a/exsamples/plugins/backlightcontrols.ino b/exsamples/plugins/backlightcontrols.ino new file mode 100644 index 0000000..cc65875 --- /dev/null +++ b/exsamples/plugins/backlightcontrols.ino @@ -0,0 +1,36 @@ +/************************************************************** + + Example of display backlight control depending on playback. + This file must be in the root directory of the sketch. + +**************************************************************/ +#include + +const uint8_t backlightPin = 13; +const uint8_t backlightInitValue = HIGH; +const uint16_t turnBlOffInterval = 120; /* 2 min */ + +Ticker backlightTicker; + +void backlightOff(){ + backlightTicker.detach(); + digitalWrite(backlightPin, !backlightInitValue); +} + +void yoradio_on_setup() { + pinMode(backlightPin, OUTPUT); + digitalWrite(backlightPin, backlightInitValue); + backlightTicker.attach(turnBlOffInterval, backlightOff); +} + +void player_on_track_change(){ + digitalWrite(backlightPin, backlightInitValue); + backlightTicker.detach(); + backlightTicker.attach(turnBlOffInterval, backlightOff); +} + +void player_on_stop_play(){ + digitalWrite(backlightPin, backlightInitValue); + backlightTicker.detach(); + backlightTicker.attach(turnBlOffInterval, backlightOff); +} diff --git a/exsamples/displayhandlers.ino b/exsamples/plugins/displayhandlers.ino similarity index 100% rename from exsamples/displayhandlers.ino rename to exsamples/plugins/displayhandlers.ino diff --git a/exsamples/plugins/rssibitrate.ino b/exsamples/plugins/rssibitrate.ino new file mode 100644 index 0000000..ce2e52c --- /dev/null +++ b/exsamples/plugins/rssibitrate.ino @@ -0,0 +1,34 @@ +/************************************************************** + + An example of replase a RSSI to bitrate information alternately. + This file must be in the root directory of the sketch. + +**************************************************************/ + +#if DSP_MODEL==DSP_ILI9225 /* your DSP_MODEL */ + +bool dsp_before_rssi(DspCore *dsp){ + static int8_t cnt; + int16_t x1, y1; + char buf[20]; /* buffer for the bitrate string */ + uint16_t w, h; /* width & height of the bitrate string */ + int16_t vTop = dsp->height() - TFT_FRAMEWDT * 2 - TFT_LINEHGHT - 2; /* vTop - Y cordnate of the bitrate string */ + + sprintf(buf, "%d kBits", config.station.bitrate); + dsp->getTextBounds(buf, 0, 0, &x1, &y1, &w, &h); + dsp->setTextSize(1); + dsp->fillRect(dsp->width() - w - TFT_FRAMEWDT-40 /* left */, vTop /* top */, w+40 /* width */, TFT_LINEHGHT-4 /* height */, TFT_BG /* background color */); + if(cnt<2){ + cnt++; + return true; /* print RSSI and retrn */ + } + cnt++; + if(cnt>3) cnt=0; + dsp->setTextColor(SILVER,TFT_BG); + dsp->setCursor(dsp->width() - w - TFT_FRAMEWDT, vTop); + dsp->print(buf); /* print bitrate */ + + return false; /* disable to print RSSI */ +} + +#endif diff --git a/yoRadio/controls.cpp b/yoRadio/controls.cpp index 752de0d..83c283c 100644 --- a/yoRadio/controls.cpp +++ b/yoRadio/controls.cpp @@ -130,6 +130,7 @@ void initControls() { void loopControls() { if(display.mode==LOST || display.mode==UPDATING) return; + if (ctrls_on_loop) ctrls_on_loop(); #if ENC_BTNL!=255 encoderLoop(); #endif diff --git a/yoRadio/controls.h b/yoRadio/controls.h index c701cc7..78c61c6 100644 --- a/yoRadio/controls.h +++ b/yoRadio/controls.h @@ -25,4 +25,6 @@ void onBtnLongPressStart(int id); void onBtnLongPressStop(int id); tsDirection_e tsDirection(uint16_t x, uint16_t y); +extern __attribute__((weak)) void ctrls_on_loop(); + #endif diff --git a/yoRadio/display.cpp b/yoRadio/display.cpp index 9ddd79f..1604d76 100644 --- a/yoRadio/display.cpp +++ b/yoRadio/display.cpp @@ -202,8 +202,7 @@ void Display::createCore0Task(){ NULL, /* parameter of the task */ 4, /* no one flies higher than the Toruk */ &TaskCore0, /* Task handle to keep track of created task */ - (DSP_MODEL==DSP_ILI9225 && VS1053_CS!=255)?xPortGetCoreID():!xPortGetCoreID()); /* pin task to core 0 */ - //delay(500); + !xPortGetCoreID()); /* pin task to core 0 */ } void loopCore0( void * pvParameters ){ @@ -518,6 +517,7 @@ void Display::title() { if (TITLE_SIZE2 != 0) title2.setText(dsp.utf8Rus(sng, true)); //dsp.loop(true); + if (player_on_track_change) player_on_track_change(); } //netserver.requestOnChange(TITLE, 0); } @@ -527,14 +527,16 @@ void Display::heap() { } void Display::rssi() { - char buf[20]; int rssi = WiFi.RSSI(); + netserver.setRSSI(rssi); + if (dsp_before_rssi) if (!dsp_before_rssi(&dsp)) return; + char buf[20]; sprintf(buf, "%ddBm", rssi); dsp.rssi(buf); - netserver.setRSSI(rssi); } void Display::ip() { + if (dsp_before_ip) if (!dsp_before_ip(&dsp)) return; dsp.ip(WiFi.localIP().toString().c_str()); } diff --git a/yoRadio/display.h b/yoRadio/display.h index 81974da..5606317 100644 --- a/yoRadio/display.h +++ b/yoRadio/display.h @@ -146,9 +146,12 @@ extern Display display; extern __attribute__((weak)) bool dsp_before_clock(DspCore *dsp, bool dots); extern __attribute__((weak)) void dsp_after_clock(DspCore *dsp, bool dots); +extern __attribute__((weak)) bool dsp_before_ip(DspCore *dsp); +extern __attribute__((weak)) bool dsp_before_rssi(DspCore *dsp); extern __attribute__((weak)) void dsp_on_init(); extern __attribute__((weak)) void dsp_on_loop(DspCore *dsp); extern __attribute__((weak)) void dsp_on_start(DspCore *dsp); extern __attribute__((weak)) void dsp_on_newmode(displayMode_e newmode); +extern __attribute__((weak)) void player_on_station_change(); #endif diff --git a/yoRadio/options.h b/yoRadio/options.h index 8b8ec15..c9d6efd 100644 --- a/yoRadio/options.h +++ b/yoRadio/options.h @@ -1,7 +1,7 @@ #ifndef options_h #define options_h -#define VERSION "0.6.320" +#define VERSION "0.6.344" /******************************************************* DO NOT EDIT THIS FILE. @@ -133,7 +133,7 @@ The connection tables are located here https://github.com/e2002/yoradio#connecti #ifndef BTN_RIGHT #define BTN_RIGHT 255 #endif -#ifndef BTN_UP +#ifndef BTN_UP5 #define BTN_UP 255 #endif #ifndef BTN_DOWN diff --git a/yoRadio/player.cpp b/yoRadio/player.cpp index af0b1a9..dee38fd 100644 --- a/yoRadio/player.cpp +++ b/yoRadio/player.cpp @@ -69,6 +69,7 @@ void Player::loop() { //stopSong(); setDefaults(); stopInfo(); + if (player_on_stop_play) player_on_stop_play(); } } if (request.station > 0) { @@ -76,6 +77,7 @@ void Player::loop() { config.setLastStation(request.station); } play(request.station); + if (player_on_station_change) player_on_station_change(); zeroRequest(); } if (request.volume >= 0) { @@ -104,6 +106,7 @@ void Player::play(uint16_t stationId) { setDefaults(); setOutputPins(false); config.setTitle("[connecting]"); + config.station.bitrate=0; netserver.requestOnChange(TITLE, 0); //telnet.printf("##CLI.META#: %s\n", config.station.title); config.loadStation(stationId); @@ -117,6 +120,7 @@ void Player::play(uint16_t stationId) { netserver.requestOnChange(MODE, 0); setOutputPins(true); requestToStart = true; + if (player_on_start_play) player_on_start_play(); }else{ Serial.println("some unknown bug..."); }; diff --git a/yoRadio/player.h b/yoRadio/player.h index 482a490..96ba08a 100644 --- a/yoRadio/player.h +++ b/yoRadio/player.h @@ -38,5 +38,8 @@ class Player: public Audio { extern Player player; +extern __attribute__((weak)) void player_on_start_play(); +extern __attribute__((weak)) void player_on_stop_play(); +extern __attribute__((weak)) void player_on_track_change(); #endif diff --git a/yoRadio/src/audioI2S/AudioEx.h b/yoRadio/src/audioI2S/AudioEx.h index b606425..d45de61 100644 --- a/yoRadio/src/audioI2S/AudioEx.h +++ b/yoRadio/src/audioI2S/AudioEx.h @@ -187,6 +187,8 @@ public: uint32_t getTotalPlayingTime(); void setDefaults(); + SemaphoreHandle_t mutex_pl=NULL; + esp_err_t i2s_mclk_pin_select(const uint8_t pin); uint32_t inBufferFilled(); // returns the number of stored bytes in the inputbuffer uint32_t inBufferFree(); // returns the number of free bytes in the inputbuffer diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp index 6e7da28..a148d1e 100644 --- a/yoRadio/src/audioVS1053/audioVS1053Ex.cpp +++ b/yoRadio/src/audioVS1053/audioVS1053Ex.cpp @@ -188,15 +188,18 @@ void Audio::control_mode_off() { CS_HIGH(); // End control mode spi_VS1053->endTransaction(); // Allow other SPI users + xSemaphoreGive(mutex_pl); } void Audio::control_mode_on() { + xSemaphoreTake(mutex_pl, portMAX_DELAY); spi_VS1053->beginTransaction(VS1053_SPI); // Prevent other SPI users DCS_HIGH(); // Bring slave in control mode CS_LOW(); } void Audio::data_mode_on() { + xSemaphoreTake(mutex_pl, portMAX_DELAY); spi_VS1053->beginTransaction(VS1053_SPI); // Prevent other SPI users CS_HIGH(); // Bring slave in data mode DCS_LOW(); @@ -206,6 +209,7 @@ void Audio::data_mode_off() //digitalWrite(dcs_pin, HIGH); // End data mode DCS_HIGH(); spi_VS1053->endTransaction(); // Allow other SPI users + xSemaphoreGive(mutex_pl); } //--------------------------------------------------------------------------------------------------------------------- uint16_t Audio::read_register(uint8_t _reg) @@ -307,6 +311,7 @@ void Audio::begin(){ pinMode(dreq_pin, INPUT); // DREQ is an input pinMode(cs_pin, OUTPUT); // The SCI and SDI signals pinMode(dcs_pin, OUTPUT); + mutex_pl = xSemaphoreCreateMutex(); DCS_HIGH(); CS_HIGH(); delay(100); diff --git a/yoRadio/src/audioVS1053/audioVS1053Ex.h b/yoRadio/src/audioVS1053/audioVS1053Ex.h index c8a94c4..17dfaa9 100644 --- a/yoRadio/src/audioVS1053/audioVS1053Ex.h +++ b/yoRadio/src/audioVS1053/audioVS1053Ex.h @@ -266,6 +266,7 @@ public: uint32_t getFilePos(); uint32_t getAudioDataStartPos(); bool setFilePos(uint32_t pos); + SemaphoreHandle_t mutex_pl=NULL; size_t bufferFilled(); size_t bufferFree(); bool isRunning() {/*Serial.printf("m_f_running=%d\n", m_f_running); */return m_f_running;} diff --git a/yoRadio/src/displays/displayGC9106.cpp b/yoRadio/src/displays/displayGC9106.cpp index be525f2..04bdf3f 100644 --- a/yoRadio/src/displays/displayGC9106.cpp +++ b/yoRadio/src/displays/displayGC9106.cpp @@ -9,9 +9,12 @@ #include "../../network.h" #ifndef DEF_SPI_FREQ -#define DEF_SPI_FREQ 40000000 /* set it to 0 for system default */ +#define DEF_SPI_FREQ 24000000 /* set it to 0 for system default */ #endif +#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) +#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) + DspCore::DspCore(): Adafruit_GC9106Ex(TFT_CS, TFT_DC, TFT_RST) { } @@ -326,6 +329,36 @@ void DspCore::ip(const char* str) { print(str); } +void DspCore::startWrite(void) { + TAKE_MUTEX(); + Adafruit_GC9106Ex::startWrite(); +} + +void DspCore::endWrite(void) { + Adafruit_GC9106Ex::endWrite(); + GIVE_MUTEX(); +} + +/* +void DspCore::sendCommand(uint8_t commandByte, uint8_t *dataBytes, uint8_t numDataBytes) { + TAKE_MUTEX(); + Adafruit_GC9106Ex::sendCommand(commandByte, dataBytes, numDataBytes); + GIVE_MUTEX(); +} + +void DspCore::sendCommand(uint8_t commandByte, const uint8_t *dataBytes, uint8_t numDataBytes) { + TAKE_MUTEX(); + Adafruit_GC9106Ex::sendCommand(commandByte, dataBytes, numDataBytes); + GIVE_MUTEX(); +} + +void DspCore::sendCommand16(uint16_t commandWord, const uint8_t *dataBytes, uint8_t numDataBytes) { + TAKE_MUTEX(); + Adafruit_GC9106Ex::sendCommand16(commandWord, dataBytes, numDataBytes); + GIVE_MUTEX(); +}*/ + + void DspCore::set_TextSize(uint8_t s) { setTextSize(s); } diff --git a/yoRadio/src/displays/displayGC9106.h b/yoRadio/src/displays/displayGC9106.h index bd2eff4..d159529 100644 --- a/yoRadio/src/displays/displayGC9106.h +++ b/yoRadio/src/displays/displayGC9106.h @@ -56,6 +56,14 @@ class DspCore: public Adafruit_GC9106Ex { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + virtual void startWrite(void); + virtual void endWrite(void); + /*virtual void sendCommand(uint8_t commandByte, uint8_t *dataBytes, + uint8_t numDataBytes); + virtual void sendCommand(uint8_t commandByte, const uint8_t *dataBytes = NULL, + uint8_t numDataBytes = 0); + virtual void sendCommand16(uint16_t commandWord, const uint8_t *dataBytes = NULL, + uint8_t numDataBytes = 0);*/ private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/src/displays/displayILI9225.cpp b/yoRadio/src/displays/displayILI9225.cpp index dbd8a9a..65068b4 100644 --- a/yoRadio/src/displays/displayILI9225.cpp +++ b/yoRadio/src/displays/displayILI9225.cpp @@ -13,6 +13,8 @@ const char *mnths[12] = {"января","февраля","марта","апре extern unsigned char yofont5x7[]; extern unsigned char yofont10x14[]; +#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) +#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) //SPIClass hspi(VSPI); DspCore::DspCore(): TFT_22_ILI9225(TFT_RST, TFT_DC, TFT_CS, 0) { @@ -109,7 +111,9 @@ void DspCore::apScreen() { print("http://"); print(WiFi.softAPIP().toString().c_str()); print("/"); + TAKE_MUTEX(); drawLine(TFT_FRAMEWDT, TITLE_TOP1-8, swidth-TFT_FRAMEWDT*2, TITLE_TOP1-8, SILVER); + GIVE_MUTEX(); } void DspCore::setTextSize(uint8_t s){ @@ -132,11 +136,14 @@ void DspCore::setCursor(int16_t x, int16_t y){ } uint16_t DspCore::print(const char* s){ + TAKE_MUTEX(); if(gFont){ drawGFXText(cursorx, cursory, s, fgcolor); + GIVE_MUTEX(); return 0; }else{ cursorx=drawText(cursorx, cursory, s, fgcolor); + GIVE_MUTEX(); return cursorx; } } @@ -175,7 +182,9 @@ void DspCore::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, h=h+y; y=0; } + TAKE_MUTEX(); fillRectangle(x, y, x+w, y+h, color); + GIVE_MUTEX(); } void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { @@ -323,10 +332,11 @@ void DspCore::printClock(struct tm timeinfo, bool dots, bool redraw){ setTextColor(TFT_FG, TFT_BG); setCursor(clleft+wot+clsp, cltop-hot+22); print(utf8Rus(dow[timeinfo.tm_wday], false)); + TAKE_MUTEX(); drawLine(clleft+wot+clsp/2, cltop-34, clleft+wot+clsp/2, cltop+1, SILVER); //vert drawLine(clleft+wot+clsp/2, cltop-hot+20, clleft+wot+clsp/2+35, cltop-hot+20, SILVER); //hor drawLine(TFT_FRAMEWDT, TITLE_TOP1-8, swidth-TFT_FRAMEWDT*2, TITLE_TOP1-8, SILVER); - + GIVE_MUTEX(); sprintf(timeBuf, "%2d %s %d", timeinfo.tm_mday,mnths[timeinfo.tm_mon], timeinfo.tm_year+1900); uint16_t wdate, hdate; getTextBounds(timeBuf, 0, 0, &x1, &y1, &wdate, &hdate); @@ -392,7 +402,9 @@ void DspCore::drawNextStationNum(uint16_t num) { void DspCore::frameTitle(const char* str) { setTextSize(META_SIZE); centerText(str, TFT_FRAMEWDT, TFT_LOGO, TFT_BG); + TAKE_MUTEX(); drawLine(TFT_FRAMEWDT, TITLE_TOP1-8, swidth-TFT_FRAMEWDT*2, TITLE_TOP1-8, SILVER); + GIVE_MUTEX(); } void DspCore::rssi(const char* str) { diff --git a/yoRadio/src/displays/displayILI9341.cpp b/yoRadio/src/displays/displayILI9341.cpp index 69acbf7..018e856 100644 --- a/yoRadio/src/displays/displayILI9341.cpp +++ b/yoRadio/src/displays/displayILI9341.cpp @@ -11,6 +11,9 @@ const char *dow[7] = {"вс","пн","вт","ср","чт","пт","сб"}; const char *mnths[12] = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}; +#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) +#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) + DspCore::DspCore(): Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST) { } @@ -303,7 +306,7 @@ void DspCore::drawVolumeBar(bool withNumber) { print(volstr);*/ sprintf(volstr, "%d", oldVolume); getTextBounds(volstr, 0, 0, &x1, &y1, &wv, &hv); - fillRect((swidth - wv) / 2 - 12, (sheight-hv)/2, wv+24, hv, TFT_BG); + fillRect((swidth - wv) / 2 - 12, (sheight-hv)/2, wv+24, hv+4, TFT_BG); setTextColor(TFT_FG); sprintf(volstr, "%d", config.store.volume); @@ -355,6 +358,16 @@ void DspCore::ip(const char* str) { print(buf); } +void DspCore::startWrite(void) { + TAKE_MUTEX(); + Adafruit_ILI9341::startWrite(); +} + +void DspCore::endWrite(void) { + Adafruit_ILI9341::endWrite(); + GIVE_MUTEX(); +} + void DspCore::set_TextSize(uint8_t s) { setTextSize(s); } diff --git a/yoRadio/src/displays/displayILI9341.h b/yoRadio/src/displays/displayILI9341.h index 2fa291d..48f3934 100644 --- a/yoRadio/src/displays/displayILI9341.h +++ b/yoRadio/src/displays/displayILI9341.h @@ -14,7 +14,7 @@ #define TITLE_SIZE2 2 #if !defined(SCROLLDELTA) || !defined(SCROLLTIME) -#define SCROLLDELTA 3 +#define SCROLLDELTA 4 #define SCROLLTIME 30 #endif @@ -56,6 +56,8 @@ class DspCore: public Adafruit_ILI9341 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + virtual void startWrite(void); + virtual void endWrite(void); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/src/displays/displayN5110.cpp b/yoRadio/src/displays/displayN5110.cpp index 5fc6fef..6900a2c 100644 --- a/yoRadio/src/displays/displayN5110.cpp +++ b/yoRadio/src/displays/displayN5110.cpp @@ -10,6 +10,9 @@ #define LOGO_WIDTH 21 #define LOGO_HEIGHT 28 +#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) +#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) + const unsigned char logo [] PROGMEM= { 0x07, 0x03, 0x80, 0x0f, 0x87, 0xc0, 0x0f, 0x87, 0xc0, 0x0f, 0x87, 0xc0, 0x0f, 0x87, 0xc0, 0x07, @@ -117,6 +120,18 @@ void DspCore::apScreen() { setFont(); } +void DspCore::command(uint8_t c) { + TAKE_MUTEX(); + Adafruit_PCD8544::command(c); + GIVE_MUTEX(); +} + +void DspCore::data(uint8_t c) { + TAKE_MUTEX(); + Adafruit_PCD8544::data(c); + GIVE_MUTEX(); +} + void DspCore::initD(uint16_t &screenwidth, uint16_t &screenheight) { begin(); setContrast(TFT_CONTRAST); diff --git a/yoRadio/src/displays/displayN5110.h b/yoRadio/src/displays/displayN5110.h index 5cf20b1..424fc90 100644 --- a/yoRadio/src/displays/displayN5110.h +++ b/yoRadio/src/displays/displayN5110.h @@ -56,6 +56,8 @@ class DspCore: public Adafruit_PCD8544 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + virtual void command(uint8_t c); + virtual void data(uint8_t c); private: uint16_t swidth, sheight; unsigned long loopdelay; diff --git a/yoRadio/src/displays/displayST7735.cpp b/yoRadio/src/displays/displayST7735.cpp index 4f08ea5..62c0198 100644 --- a/yoRadio/src/displays/displayST7735.cpp +++ b/yoRadio/src/displays/displayST7735.cpp @@ -16,6 +16,9 @@ #define DEF_SPI_FREQ 40000000UL /* set it to 0 for system default */ #endif +#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) +#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) + DspCore::DspCore(): Adafruit_ST7735(&SPI, TFT_CS, TFT_DC, TFT_RST) { } @@ -362,6 +365,16 @@ void DspCore::ip(const char* str) { print(str); } +void DspCore::startWrite(void) { + TAKE_MUTEX(); + Adafruit_ST7735::startWrite(); +} + +void DspCore::endWrite(void) { + Adafruit_ST7735::endWrite(); + GIVE_MUTEX(); +} + void DspCore::set_TextSize(uint8_t s) { setTextSize(s); } diff --git a/yoRadio/src/displays/displayST7735.h b/yoRadio/src/displays/displayST7735.h index 4dd1e04..c17966a 100644 --- a/yoRadio/src/displays/displayST7735.h +++ b/yoRadio/src/displays/displayST7735.h @@ -67,6 +67,8 @@ class DspCore: public Adafruit_ST7735 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + virtual void startWrite(void); + virtual void endWrite(void); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/src/displays/displayST7789.cpp b/yoRadio/src/displays/displayST7789.cpp index ac4fa6d..2458821 100644 --- a/yoRadio/src/displays/displayST7789.cpp +++ b/yoRadio/src/displays/displayST7789.cpp @@ -15,6 +15,9 @@ const char *dow[7] = {"вс","пн","вт","ср","чт","пт","сб"}; const char *mnths[12] = {"января","февраля","марта","апреля","мая","июня","июля","августа","сентября","октября","ноября","декабря"}; +#define TAKE_MUTEX() if(player.mutex_pl) xSemaphoreTake(player.mutex_pl, portMAX_DELAY) +#define GIVE_MUTEX() if(player.mutex_pl) xSemaphoreGive(player.mutex_pl) + DspCore::DspCore(): Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST) { } @@ -350,6 +353,16 @@ void DspCore::ip(const char* str) { print(buf); } +void DspCore::startWrite(void) { + TAKE_MUTEX(); + Adafruit_ST7789::startWrite(); +} + +void DspCore::endWrite(void) { + Adafruit_ST7789::endWrite(); + GIVE_MUTEX(); +} + void DspCore::set_TextSize(uint8_t s) { setTextSize(s); } diff --git a/yoRadio/src/displays/displayST7789.h b/yoRadio/src/displays/displayST7789.h index 858067a..1c5b0aa 100644 --- a/yoRadio/src/displays/displayST7789.h +++ b/yoRadio/src/displays/displayST7789.h @@ -14,7 +14,7 @@ #define TITLE_SIZE2 2 #if !defined(SCROLLDELTA) || !defined(SCROLLTIME) -#define SCROLLDELTA 3 +#define SCROLLDELTA 4 #define SCROLLTIME 30 #endif @@ -56,6 +56,8 @@ class DspCore: public Adafruit_ST7789 { void ip(const char* str); void drawPlaylist(uint16_t currentItem, char* currentItemText); void loop(bool force=false); + virtual void startWrite(void); + virtual void endWrite(void); private: uint16_t swidth, sheight; char oldTimeBuf[20]; diff --git a/yoRadio/yoRadio.ino b/yoRadio/yoRadio.ino index e1f0d7f..90f7460 100644 --- a/yoRadio/yoRadio.ino +++ b/yoRadio/yoRadio.ino @@ -17,9 +17,11 @@ unsigned long checkMillis = 0; unsigned long checkInterval = 3000; +extern __attribute__((weak)) void yoradio_on_setup(); void setup() { Serial.begin(115200); pinMode(LED_BUILTIN, OUTPUT); + if (yoradio_on_setup) yoradio_on_setup(); config.init(); display.init(); player.init();