diff --git a/ESP32_AP-Flasher/include/serialconsole.h b/ESP32_AP-Flasher/include/serialconsole.h new file mode 100644 index 00000000..83b50de2 --- /dev/null +++ b/ESP32_AP-Flasher/include/serialconsole.h @@ -0,0 +1,8 @@ +#include +extern QueueHandle_t consoleCmdQueue; +extern TaskHandle_t consoleTaskHandle; + + +void consoleStopTask(); +void consoleTask(void* parameter); +void consoleUartHandler(uint8_t* data, uint8_t len); \ No newline at end of file diff --git a/ESP32_AP-Flasher/include/settings.h b/ESP32_AP-Flasher/include/settings.h index 2ba4b56f..22a539ea 100644 --- a/ESP32_AP-Flasher/include/settings.h +++ b/ESP32_AP-Flasher/include/settings.h @@ -10,70 +10,4 @@ // flasher options #define CUSTOM_MAC_HDR 0x0000 -#if (PINOUT == OPENEPAPERLINK_PCB) -#define FLASHER_AP_SS 4 -#define FLASHER_AP_CLK 5 -#define FLASHER_AP_MOSI 7 -#define FLASHER_AP_MISO 6 -#define FLASHER_AP_RESET 15 -#define FLASHER_AP_POWER 0 //switching LOW side; connect to GND of tag -#define FLASHER_AP_TXD 16 -#define FLASHER_AP_RXD 18 -#define FLASHER_AP_TEST 17 - -#define FLASHER_EXT_SS 40 -#define FLASHER_EXT_CLK 41 -#define FLASHER_EXT_MOSI 2 -#define FLASHER_EXT_MISO 42 -#define FLASHER_EXT_RESET 1 -#define FLASHER_EXT_POWER 8 -#define FLASHER_EXT_TXD 38 -#define FLASHER_EXT_RXD 39 -#define FLASHER_EXT_TEST 47 - -#define FLASHER_ALT_SS 3 -#define FLASHER_ALT_CLK 46 -#define FLASHER_ALT_MOSI 10 -#define FLASHER_ALT_MISO 9 -#define FLASHER_ALT_RESET 11 -#define FLASHER_ALT_TXD 12 -#define FLASHER_ALT_RXD 14 -#define FLASHER_ALT_TEST 13 - -#define FLASHER_LED 21 -#define FLASHER_RGB_LED 48 -#endif - -#if (PINOUT == SIMPLE_AP) -/* Lolin32 lite connections to AP tag*/ -#define FLASHER_AP_SS 5 -#define FLASHER_AP_CLK 18 -#define FLASHER_AP_MOSI 23 -#define FLASHER_AP_MISO 19 -#define FLASHER_AP_RESET 2 -#define FLASHER_AP_POWER 13 // switching HIGH side; connect to 3V3 of tag -#define FLASHER_AP_POWER2 15 -#define FLASHER_AP_TEST -1 -#define FLASHER_AP_TXD 17 -#define FLASHER_AP_RXD 16 - -#define FLASHER_LED 22 -#endif - -#if (PINOUT == AlternativePCB) -/* Lolin32 lite connections to AP tag*/ -#define FLASHER_AP_SS 22 -#define FLASHER_AP_CLK 13 -#define FLASHER_AP_MOSI 23 -#define FLASHER_AP_MISO 33 -#define FLASHER_AP_RESET 27 -#define FLASHER_AP_POWER 4 -#define FLASHER_AP_POWER2 4 -#define FLASHER_AP_TEST -1 -#define FLASHER_AP_TXD 26 -#define FLASHER_AP_RXD 25 - -#define FLASHER_LED 19 -#endif - -#define MAX_WRITE_ATTEMPTS 5 +#define MAX_WRITE_ATTEMPTS 5 \ No newline at end of file diff --git a/ESP32_AP-Flasher/platformio.ini b/ESP32_AP-Flasher/platformio.ini index 2e9f460f..b87f2863 100644 --- a/ESP32_AP-Flasher/platformio.ini +++ b/ESP32_AP-Flasher/platformio.ini @@ -8,20 +8,9 @@ ; Please visit documentation for the other options and examples ; https://docs.platformio.org/page/projectconf.html -; ---------------------------------------------------------------------------------------- -; !!! this configuration expects the 16MB Flash / 8MB Ram version of the ESP32-S3-DevkitC1 -; ---------------------------------------------------------------------------------------- - -[env:OpenEPaperLink-AP-Flasher] -platform = https://github.com/platformio/platform-espressif32.git -board = esp32-s3-devkitc-1 +[env] +platform = espressif32 framework = arduino -board_build.partitions = default_16MB.csv -platform_packages = -monitor_filters = esp32_exception_decoder -monitor_speed = 115200 -board_build.f_cpu = 240000000L -board_build.filesystem = littlefs lib_deps = https://github.com/me-no-dev/ESPAsyncWebServer https://github.com/tzapu/WiFiManager.git#feature_asyncwebserver @@ -30,22 +19,105 @@ lib_deps = https://github.com/Bodmer/TJpg_Decoder.git https://github.com/garretlab/shoddyxml2 https://github.com/Bodmer/U8g2_for_TFT_eSPI - https://github.com/ricmoo/qrcode + https://github.com/ricmoo/qrcode fastled/FastLED -upload_port = COM17 -monitor_port = COM17 +platform_packages = +board_build.filesystem = littlefs +monitor_filters = esp32_exception_decoder +monitor_speed = 115200 +board_build.f_cpu = 240000000L +;upload_port = COM30 +;monitor_port = COM30 + + +[env:OpenEPaperLink Mini AP] +platform = https://github.com/platformio/platform-espressif32.git +board=lolin_s2_mini +board_build.partitions = default.csv +build_flags = + -D OPENEPAPERLINK_MINI_AP_PCB + -D ARDUINO_USB_MODE=0 + -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 + -D CONFIG_SPIRAM_USE_MALLOC=y + -D HAS_RGB_LED + -D BOARD_HAS_PSRAM + ;-D HAS_USB + + -D FLASHER_AP_SS=11 + -D FLASHER_AP_CLK=9 + -D FLASHER_AP_MOSI=10 + -D FLASHER_AP_MISO=8 + -D FLASHER_AP_RESET=13 + -D FLASHER_AP_POWER=-1 ;this board has no soft power control + -D FLASHER_AP_TXD=7 + -D FLASHER_AP_RXD=6 + -D FLASHER_AP_TEST=12 + -D FLASHER_LED=15 + -D FLASHER_RGB_LED=33 + + +build_src_filter = + +<*>-- + +board_build.psram_type=qspi_opi +board_upload.maximum_size = 4194304 +;board_upload.maximum_ram_size = 327680 +board_upload.maximum_ram_size = 2097152 +board_upload.flash_size = 4MB + + +; ---------------------------------------------------------------------------------------- +; !!! this configuration expects the 16MB Flash / 8MB Ram version of the ESP32-S3-DevkitC1 +; +; ---------------------------------------------------------------------------------------- +[env:OpenEPaperLink AP and Flasher] +platform = https://github.com/platformio/platform-espressif32.git +board = esp32-s3-devkitc-1 +board_build.partitions = default_16MB.csv + build_unflags = -D ARDUINO_USB_MODE=1 build_flags = - -D OPENEPAPERLINK_PCB=1 - -D ARDUINO_USB_MODE=0 - -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 - -D BOARD_HAS_PSRAM - -D CONFIG_SPIRAM_USE_MALLOC=y - -D PINOUT=OPENEPAPERLINK_PCB - -D HAS_USB=1 + -D OPENEPAPERLINK_PCB + -D ARDUINO_USB_MODE=0 + -D CONFIG_ESP32S3_SPIRAM_SUPPORT=1 + -D CONFIG_SPIRAM_USE_MALLOC=y + -D HAS_USB + -D HAS_RGB_LED + -D BOARD_HAS_PSRAM + + -D FLASHER_AP_SS=4 + -D FLASHER_AP_CLK=5 + -D FLASHER_AP_MOSI=7 + -D FLASHER_AP_MISO=6 + -D FLASHER_AP_RESET=15 + -D FLASHER_AP_POWER=0 + -D FLASHER_AP_TXD=16 + -D FLASHER_AP_RXD=18 + -D FLASHER_AP_TEST=17 + + -D FLASHER_EXT_SS=40 + -D FLASHER_EXT_CLK=41 + -D FLASHER_EXT_MOSI=2 + -D FLASHER_EXT_MISO=42 + -D FLASHER_EXT_RESET=1 + -D FLASHER_EXT_POWER=8 + -D FLASHER_EXT_TXD=38 + -D FLASHER_EXT_RXD=39 + -D FLASHER_EXT_TEST=47 + + -D FLASHER_ALT_SS=3 + -D FLASHER_ALT_CLK=46 + -D FLASHER_ALT_MOSI=10 + -D FLASHER_ALT_MISO=9 + -D FLASHER_ALT_RESET=11 + -D FLASHER_ALT_TXD=12 + -D FLASHER_ALT_RXD=14 + -D FLASHER_ALT_TEST=13 + + -D FLASHER_LED=21 + -D FLASHER_RGB_LED=48 - board_build.flash_mode=qio board_build.arduino.memory_type = qio_opi board_build.psram_type=qspi_opi @@ -54,60 +126,50 @@ board_upload.maximum_size = 16777216 board_upload.maximum_ram_size = 327680 board_upload.flash_size = 16MB -[env:Simple_AP] -platform = espressif32 +[env:Simple AP] board = esp32dev -framework = arduino board_build.partitions = no_ota.csv -platform_packages = -monitor_filters = esp32_exception_decoder -monitor_speed = 115200 -board_build.f_cpu = 240000000L -board_build.filesystem = littlefs -lib_deps = - https://github.com/me-no-dev/ESPAsyncWebServer - https://github.com/tzapu/WiFiManager.git#feature_asyncwebserver - bblanchon/ArduinoJson - bodmer/TFT_eSPI - https://github.com/Bodmer/TJpg_Decoder.git - https://github.com/garretlab/shoddyxml2 - https://github.com/Bodmer/U8g2_for_TFT_eSPI - https://github.com/ricmoo/qrcode -upload_port = COM21 -monitor_port = COM21 build_flags = - -D SIMPLE_AP=2 - -D PINOUT=SIMPLE_AP + -D SIMPLE_AP + + -D FLASHER_AP_SS=5 + -D FLASHER_AP_CLK=18 + -D FLASHER_AP_MOSI=23 + -D FLASHER_AP_MISO=19 + -D FLASHER_AP_RESET=2 + -D FLASHER_AP_POWER=13 ;// switching HIGH side; connect to 3V3 of tag + -D FLASHER_AP_POWER2=15 + -D FLASHER_AP_TEST=-1 + -D FLASHER_AP_TXD=17 + -D FLASHER_AP_RXD=16 + + -D FLASHER_LED=22 + build_src_filter = - +<*>- + +<*>-- ; ---------------------------------------------------------------------------------------- ; !!! this configuration expects the alternative 2.9" Flasher PCB ; ---------------------------------------------------------------------------------------- -[env:AlternativePCB] -platform = espressif32 +[env:Alternative PCB] board = esp32dev -framework = arduino board_build.partitions = no_ota.csv -platform_packages = -monitor_filters = esp32_exception_decoder -monitor_speed = 115200 -board_build.f_cpu = 240000000L -board_build.filesystem = littlefs -lib_deps = - https://github.com/me-no-dev/ESPAsyncWebServer - https://github.com/tzapu/WiFiManager.git#feature_asyncwebserver - bblanchon/ArduinoJson - bodmer/TFT_eSPI - https://github.com/Bodmer/TJpg_Decoder.git - https://github.com/garretlab/shoddyxml2 - https://github.com/Bodmer/U8g2_for_TFT_eSPI - https://github.com/ricmoo/qrcode build_flags = - -D SIMPLE_AP=2 - -D PINOUT=AlternativePCB + -D ALTERNATIVE_PCB + -D FLASHER_AP_SS=22 + -D FLASHER_AP_CLK=13 + -D FLASHER_AP_MOSI=23 + -D FLASHER_AP_MISO=33 + -D FLASHER_AP_RESET=27 + -D FLASHER_AP_POWER=4 + -D FLASHER_AP_POWER2=4 + -D FLASHER_AP_TEST=-1 + -D FLASHER_AP_TXD=26 + -D FLASHER_AP_RXD=25 + + -D FLASHER_LED=19 build_src_filter = - +<*>- + +<*>-- diff --git a/ESP32_AP-Flasher/src/contentmanager.cpp b/ESP32_AP-Flasher/src/contentmanager.cpp index 4beb2238..f67aeb8f 100644 --- a/ESP32_AP-Flasher/src/contentmanager.cpp +++ b/ESP32_AP-Flasher/src/contentmanager.cpp @@ -39,7 +39,7 @@ void contentRunner() { time(&now); for (int16_t c = 0; c < tagDB.size(); c++) { - tagRecord* taginfo = nullptr; + tagRecord *taginfo = nullptr; taginfo = tagDB.at(c); if (taginfo->RSSI && (now >= taginfo->nextupdate || taginfo->wakeupReason == WAKEUP_REASON_GPIO)) { @@ -51,6 +51,7 @@ void contentRunner() { drawNew(src, (taginfo->wakeupReason == WAKEUP_REASON_GPIO), taginfo); taginfo->wakeupReason = 0; } + vTaskDelay(1/portTICK_PERIOD_MS); // add a small delay to allow other threads to run } } @@ -80,12 +81,12 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { wsLog("Updating " + dst); taginfo->nextupdate = now + 60; - + imgParam imageParams; imageParams.hasRed = false; imageParams.dataType = DATATYPE_IMG_RAW_1BPP; - switch (taginfo->contentMode) { + switch (taginfo->contentMode) { case Image: if (cfgobj["filename"].as() && cfgobj["filename"].as() != "null" && !cfgobj["#fetched"].as()) { @@ -153,7 +154,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { } else { wsErr("Error accessing " + filename); } - cfgobj["filename"]=""; + cfgobj["filename"] = ""; taginfo->nextupdate = 3216153600; taginfo->contentMode = Image; } else { @@ -205,8 +206,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) { taginfo->nextupdate = now + 300; } break; - - } + } taginfo->modeConfigJson = doc.as(); } @@ -217,7 +217,7 @@ bool updateTagImage(String &filename, uint8_t *dst, uint16_t nextCheckin, imgPar return true; } -void drawString(TFT_eSprite &spr, String content, uint16_t posx, uint16_t posy, String font, byte align,uint16_t color) { +void drawString(TFT_eSprite &spr, String content, uint16_t posx, uint16_t posy, String font, byte align, uint16_t color) { // drawString(spr,"test",100,10,"bahnschrift30",TC_DATUM,PAL_RED); spr.setTextDatum(align); if (font != "") spr.loadFont(font, LittleFS); @@ -248,21 +248,19 @@ void drawDate(String &filename, tagRecord *&taginfo, imgParam &imageParams) { struct tm timeinfo; localtime_r(&now, &timeinfo); - String Dag[] = {"zondag","maandag","dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"}; - String Maand[] = {"januari", "februari", "maart", "april", "mei", "juni","juli", "augustus", "september", "oktober", "november", "december"}; + String Dag[] = {"zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"}; + String Maand[] = {"januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"}; int weekday_number = timeinfo.tm_wday; int month_number = timeinfo.tm_mon; LittleFS.begin(); if (taginfo->hwType == SOLUM_29_033) { - - initSprite(spr,296,128); + initSprite(spr, 296, 128); drawString(spr, Dag[timeinfo.tm_wday], 296 / 2, 10, "fonts/calibrib62", TC_DATUM, PAL_RED); drawString(spr, String(timeinfo.tm_mday) + " " + Maand[timeinfo.tm_mon], 296 / 2, 73, "fonts/calibrib50", TC_DATUM); } else if (taginfo->hwType == SOLUM_154_033) { - initSprite(spr, 152, 152); drawString(spr, Dag[timeinfo.tm_wday], 152 / 2, 10, "fonts/calibrib30", TC_DATUM); drawString(spr, String(Maand[timeinfo.tm_mon]), 152 / 2, 120, "fonts/calibrib30", TC_DATUM); @@ -279,7 +277,6 @@ void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord LittleFS.begin(); if (taginfo->hwType == SOLUM_29_033) { - initSprite(spr, 296, 128); spr.setTextDatum(MC_DATUM); if (count > thresholdred) { @@ -295,7 +292,6 @@ void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord spr.unloadFont(); } else if (taginfo->hwType == SOLUM_154_033) { - initSprite(spr, 152, 152); spr.setTextDatum(MC_DATUM); if (count > thresholdred) { @@ -309,7 +305,6 @@ void drawNumber(String &filename, int32_t count, int32_t thresholdred, tagRecord spr.loadFont(font, LittleFS); spr.drawString(String(count), 152 / 2, 152 / 2 + 7); spr.unloadFont(); - } spr2buffer(spr, filename, imageParams); @@ -325,8 +320,10 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo, imgPara http.begin("https://geocoding-api.open-meteo.com/v1/search?name=" + urlEncode(location.c_str()) + "&count=1"); http.setTimeout(5000); // timeout in ms int httpCode = http.GET(); - if (httpCode == 200) { + Serial.printf("Got code %d for this location\n", httpCode); + Serial.print(http.errorToString(httpCode)); + if (httpCode == 200) { StaticJsonDocument<1000> doc; DeserializationError error = deserializeJson(doc, http.getStream()); http.end(); @@ -334,9 +331,9 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo, imgPara http.begin("https://api.open-meteo.com/v1/forecast?latitude=" + doc["results"][0]["latitude"].as() + "&longitude=" + doc["results"][0]["longitude"].as() + "¤t_weather=true&windspeed_unit=ms&timezone=" + doc["results"][0]["timezone"].as()); http.setTimeout(5000); // timeout in ms int httpCode = http.GET(); + Serial.printf("Got code %d for this OpenMeteo\n", httpCode); if (httpCode == 200) { - StaticJsonDocument<200> filter; filter["current_weather"]["temperature"] = true; filter["current_weather"]["windspeed"] = true; @@ -358,12 +355,12 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo, imgPara int wind = windSpeedToBeaufort(windspeed); String weatherIcons[] = {"\uf00d", "\uf00c", "\uf002", "\uf013", "\uf013", "\uf014", "-", "-", "\uf014", "-", "-", - "\uf01a", "-", "\uf01a", "-", "\uf01a", "\uf017", "\uf017", "-", "-", "-", - "\uf019", "-", "\uf019", "-", "\uf019", "\uf015", "\uf015", "-", "-", "-", - "\uf01b", "-", "\uf01b", "-", "\uf01b", "-", "\uf076", "-", "-", "\uf01a", - "\uf01a", "\uf01a", "-", "-", "\uf064", "\uf064", "-", "-", "-", "-", - "-", "-", "-", "-", "\uf01e", "\uf01d", "-", "-", "\uf01e"}; - if (1==0) { //nacht + "\uf01a", "-", "\uf01a", "-", "\uf01a", "\uf017", "\uf017", "-", "-", "-", + "\uf019", "-", "\uf019", "-", "\uf019", "\uf015", "\uf015", "-", "-", "-", + "\uf01b", "-", "\uf01b", "-", "\uf01b", "-", "\uf076", "-", "-", "\uf01a", + "\uf01a", "\uf01a", "-", "-", "\uf064", "\uf064", "-", "-", "-", "-", + "-", "-", "-", "-", "\uf01e", "\uf01d", "-", "-", "\uf01e"}; + if (1 == 0) { // nacht weatherIcons[0] = "\0uf02e"; weatherIcons[1] = "\0uf083"; weatherIcons[2] = "\0uf086"; @@ -372,10 +369,9 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo, imgPara doc.clear(); LittleFS.begin(); - tft.setTextWrap(false,false); + tft.setTextWrap(false, false); if (taginfo->hwType == SOLUM_29_033) { - initSprite(spr, 296, 128); drawString(spr, location, 5, 5, "fonts/bahnschrift30"); @@ -408,7 +404,6 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo, imgPara spr.unloadFont(); } else if (taginfo->hwType == SOLUM_154_033) { - initSprite(spr, 152, 152); spr.setTextDatum(TL_DATUM); @@ -443,7 +438,6 @@ void drawWeather(String &filename, String location, tagRecord *&taginfo, imgPara spr.printToSprite("\uf084"); } spr.unloadFont(); - } spr2buffer(spr, filename, imageParams); @@ -483,7 +477,7 @@ void drawForecast(String &filename, String location, tagRecord *&taginfo, imgPar filter["daily"]["windspeed_10m_max"][0] = true; filter["daily"]["winddirection_10m_dominant"][0] = true; - //DeserializationError error = deserializeJson(doc, http.getString(), DeserializationOption::Filter(filter)); + // DeserializationError error = deserializeJson(doc, http.getString(), DeserializationOption::Filter(filter)); DeserializationError error = deserializeJson(doc, http.getString()); if (error) { Serial.println(F("deserializeJson() failed: ")); @@ -541,13 +535,12 @@ void drawForecast(String &filename, String location, tagRecord *&taginfo, imgPar drawString(spr, String(" ") + String(tmax), dag * 59 + 30, 108, "", TL_DATUM, (tmax < 0 ? PAL_RED : PAL_BLACK)); drawString(spr, String(" ") + String(wind), dag * 59 + 30, 43, "", TL_DATUM, (wind > 5 ? PAL_RED : PAL_BLACK)); spr.unloadFont(); - if (dag>0) { - for (int i = 20; i < 128; i+=3) { + if (dag > 0) { + for (int i = 20; i < 128; i += 3) { spr.drawPixel(dag * 59, i, PAL_BLACK); } } } - } spr2buffer(spr, filename, imageParams); spr.deleteSprite(); @@ -580,12 +573,12 @@ bool getImgURL(String &filename, String URL, time_t fetched, imgParam &imagePara // https://images.klari.net/kat-bw29.jpg LittleFS.begin(); - + Serial.println("get external " + URL); HTTPClient http; http.begin(URL); http.addHeader("If-Modified-Since", formatHttpDate(fetched)); - http.setTimeout(5000); //timeout in ms + http.setTimeout(5000); // timeout in ms int httpCode = http.GET(); if (httpCode == 200) { File f = LittleFS.open("/temp/temp.jpg", "w"); @@ -595,7 +588,7 @@ bool getImgURL(String &filename, String URL, time_t fetched, imgParam &imagePara jpg2buffer("/temp/temp.jpg", filename, imageParams); } } else { - if (httpCode!=304) { + if (httpCode != 304) { wsErr("http " + URL + " " + String(httpCode)); } else { wsLog("http " + URL + " " + String(httpCode)); @@ -631,7 +624,7 @@ bool getRssFeed(String &filename, String URL, String title, tagRecord *&taginfo, if (taginfo->hwType == SOLUM_29_033) { initSprite(spr, 296, 128); - if (title=="" || title=="null") title="RSS feed"; + if (title == "" || title == "null") title = "RSS feed"; drawString(spr, title, 5, 3, "fonts/bahnschrift20", TL_DATUM, PAL_RED); u8f.setFont(u8g2_font_glasstown_nbp_tr); // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall @@ -650,7 +643,7 @@ bool getRssFeed(String &filename, String URL, String title, tagRecord *&taginfo, int n = reader.getArticles(url, tag, rssArticleSize, rssNumArticle); for (int i = 0; i < n; i++) { - u8f.setCursor(5, 34+i*13); // start writing at this position + u8f.setCursor(5, 34 + i * 13); // start writing at this position u8f.print(reader.itemData[i]); } } @@ -733,14 +726,14 @@ bool getCalFeed(String &filename, String URL, String title, tagRecord *&taginfo, // select u8g2 font from here: https://github.com/olikraus/u8g2/wiki/fntlistall int n = doc.size(); - if (n>7) n=7; + if (n > 7) n = 7; for (int i = 0; i < n; i++) { JsonObject obj = doc[i]; String eventtitle = obj["title"]; String startz = obj["start"]; time_t starttime = obj["start"]; time_t endtime = obj["end"]; - if (starttimenow) { + if (starttime < now && endtime > now) { u8f.setFont(u8g2_font_t0_14b_tr); u8f.setForegroundColor(PAL_WHITE); u8f.setBackgroundColor(PAL_RED); @@ -780,7 +773,7 @@ void drawQR(String &filename, String qrcontent, String title, tagRecord *&taginf initSprite(spr, 296, 128); drawString(spr, title, 10, 5, "fonts/bahnschrift20"); dotsize = int((128 - 25) / size); - xpos = 149 - dotsize*size /2; + xpos = 149 - dotsize * size / 2; ypos = 25; } else if (taginfo->hwType == SOLUM_154_033) { initSprite(spr, 152, 152); @@ -788,7 +781,7 @@ void drawQR(String &filename, String qrcontent, String title, tagRecord *&taginf spr.setTextColor(PAL_BLACK, PAL_WHITE); spr.drawString(title, 10, 5); dotsize = int((152 - 20) / size); - xpos = 76 - dotsize*size / 2; + xpos = 76 - dotsize * size / 2; ypos = 20; } diff --git a/ESP32_AP-Flasher/src/leds.cpp b/ESP32_AP-Flasher/src/leds.cpp index af182aec..7f5c164a 100644 --- a/ESP32_AP-Flasher/src/leds.cpp +++ b/ESP32_AP-Flasher/src/leds.cpp @@ -1,6 +1,6 @@ #include -#ifdef OPENEPAPERLINK_PCB +#ifdef HAS_RGB_LED #include #endif @@ -9,7 +9,7 @@ QueueHandle_t ledQueue; -#ifdef OPENEPAPERLINK_PCB +#ifdef HAS_RGB_LED QueueHandle_t rgbLedQueue; struct ledInstructionRGB { @@ -75,7 +75,7 @@ const uint16_t gamma12[256] = { -#ifdef OPENEPAPERLINK_PCB +#ifdef HAS_RGB_LED void addToRGBQueue(struct ledInstructionRGB* rgb) { BaseType_t queuestatus = xQueueSend(rgbLedQueue, &rgb, 0); @@ -194,7 +194,7 @@ void monoIdleStep() { } void ledTask(void* parameter) { -#ifdef OPENEPAPERLINK_PCB +#ifdef HAS_RGB_LED FastLED.addLeds(leds, 1); // GRB ordering is typical leds[0] = CRGB::Blue; showRGB(); @@ -232,7 +232,7 @@ void ledTask(void* parameter) { uint16_t monoInstructionFadeTime = 0; while (1) { -#ifdef OPENEPAPERLINK_PCB +#ifdef HAS_RGB_LED // handle RGB led instructions if (rgb == nullptr) { // fetch a led instruction diff --git a/ESP32_AP-Flasher/src/main.cpp b/ESP32_AP-Flasher/src/main.cpp index 75fa3a4b..54885b13 100644 --- a/ESP32_AP-Flasher/src/main.cpp +++ b/ESP32_AP-Flasher/src/main.cpp @@ -5,14 +5,14 @@ #include "contentmanager.h" #include "flasher.h" -#include "hal/wdt_hal.h" +//#include "hal/wdt_hal.h" #include "makeimage.h" #include "pendingdata.h" #include "serial.h" #include "settings.h" #include "tag_db.h" -#if (HAS_USB == 1) +#ifdef HAS_USB #include "usbflasher.h" #endif @@ -58,7 +58,7 @@ void setup() { Serial.printf("Total PSRAM: %d", ESP.getPsramSize()); Serial.printf("Free PSRAM: %d", ESP.getFreePsram()); - #ifdef OPENEPAPERLINK_PCB + #ifdef HAS_USB xTaskCreate(usbFlasherTask, "flasher", 10000, NULL, configMAX_PRIORITIES - 10, NULL); #endif diff --git a/ESP32_AP-Flasher/src/serial.cpp b/ESP32_AP-Flasher/src/serial.cpp index 1de248b7..b24071fb 100644 --- a/ESP32_AP-Flasher/src/serial.cpp +++ b/ESP32_AP-Flasher/src/serial.cpp @@ -31,6 +31,8 @@ SemaphoreHandle_t txActive; #define CMD_REPLY_NOQ 0x03 volatile uint8_t cmdReplyValue = CMD_REPLY_WAIT; +#define AP_SERIAL_PORT Serial1 + bool txStart() { while (1) { if (xPortInIsrContext()) { @@ -68,6 +70,7 @@ bool waitCmdReply() { return false; break; } + vTaskDelay(1 / portTICK_RATE_MS); } return false; } @@ -76,7 +79,7 @@ uint16_t sendBlock(const void* data, const uint16_t len) { if (!txStart()) return 0; for (uint8_t attempt = 0; attempt < 5; attempt++) { cmdReplyValue = CMD_REPLY_WAIT; - Serial1.print(">D>"); + AP_SERIAL_PORT.print(">D>"); if (waitCmdReply()) goto blksend; Serial.printf("block send failed in try %d\n", attempt); } @@ -96,23 +99,23 @@ blksend: // send blockData header for (uint8_t c = 0; c < sizeof(struct blockData); c++) { - Serial1.write(0xAA ^ blockbuffer[c]); + AP_SERIAL_PORT.write(0xAA ^ blockbuffer[c]); } // send an entire block of data uint16_t c; for (c = 0; c < len; c++) { - Serial1.write(0xAA ^ ((uint8_t*)data)[c]); + AP_SERIAL_PORT.write(0xAA ^ ((uint8_t*)data)[c]); } // fill the rest of the block-length filled with something else (will end up as 0xFF in the buffer) for (; c < BLOCK_DATA_SIZE; c++) { - Serial1.write(0x55); + AP_SERIAL_PORT.write(0x55); } // dummy bytes in case some bytes were missed, makes sure the AP gets kicked out of data-loading mode for (c = 0; c < 32; c++) { - Serial1.write(0xF5); + AP_SERIAL_PORT.write(0xF5); } delay(10); txEnd(); @@ -124,9 +127,9 @@ void sendDataAvail(struct pendingData* pending) { addCRC(pending, sizeof(struct pendingData)); for (uint8_t attempt = 0; attempt < 5; attempt++) { cmdReplyValue = CMD_REPLY_WAIT; - Serial1.print("SDA>"); + AP_SERIAL_PORT.print("SDA>"); for (uint8_t c = 0; c < sizeof(struct pendingData); c++) { - Serial1.write(((uint8_t*)pending)[c]); + AP_SERIAL_PORT.write(((uint8_t*)pending)[c]); } if (waitCmdReply()) goto sdasend; Serial.printf("SDA send failed in try %d\n", attempt); @@ -144,14 +147,14 @@ void sendCancelPending(struct pendingData* pending) { addCRC(pending, sizeof(struct pendingData)); for (uint8_t attempt = 0; attempt < 5; attempt++) { cmdReplyValue = CMD_REPLY_WAIT; - Serial1.print("CXD>"); + AP_SERIAL_PORT.print("CXD>"); for (uint8_t c = 0; c < sizeof(struct pendingData); c++) { - Serial1.write(((uint8_t*)pending)[c]); + AP_SERIAL_PORT.write(((uint8_t*)pending)[c]); } if (waitCmdReply()) goto cxdsend; - Serial.printf("CXD send failed in try %d\n", attempt); + AP_SERIAL_PORT.printf("CXD send failed in try %d\n", attempt); } - Serial.print("CXD failed to send...\n"); + AP_SERIAL_PORT.print("CXD failed to send...\n"); txEnd(); return; cxdsend: @@ -164,7 +167,7 @@ uint16_t version; void Ping() { if (!txStart()) return; - Serial1.print("VER?"); + AP_SERIAL_PORT.print("VER?"); txEnd(); waitingForVersion = esp_timer_get_time(); } @@ -230,8 +233,8 @@ void SerialRXLoop() { static char lastchar = 0; static uint8_t charindex = 0; - while (Serial1.available()) { - lastchar = Serial1.read(); + while (AP_SERIAL_PORT.available()) { + lastchar = AP_SERIAL_PORT.read(); switch (RXState) { case ZBS_RX_WAIT_HEADER: Serial.write(lastchar); @@ -330,7 +333,7 @@ extern uint8_t* getDataForFile(File* file); void zbsRxTask(void* parameter) { xTaskCreate(rxCmdProcessor, "rxCmdProcessor", 10000, NULL, configMAX_PRIORITIES - 10, NULL); - Serial1.begin(115200, SERIAL_8N1, FLASHER_AP_RXD, FLASHER_AP_TXD); + AP_SERIAL_PORT.begin(115200, SERIAL_8N1, FLASHER_AP_RXD, FLASHER_AP_TXD); pinMode(FLASHER_AP_RESET, OUTPUT); digitalWrite(FLASHER_AP_RESET, LOW); @@ -343,14 +346,14 @@ void zbsRxTask(void* parameter) { bool firstrun = true; - Serial1.print("VER?"); + AP_SERIAL_PORT.print("VER?"); waitingForVersion = esp_timer_get_time(); while (1) { SerialRXLoop(); if (Serial.available()) { - Serial1.write(Serial.read()); + AP_SERIAL_PORT.write(Serial.read()); } vTaskDelay(1 / portTICK_PERIOD_MS); diff --git a/ESP32_AP-Flasher/src/serialconsole.cpp b/ESP32_AP-Flasher/src/serialconsole.cpp new file mode 100644 index 00000000..4e778472 --- /dev/null +++ b/ESP32_AP-Flasher/src/serialconsole.cpp @@ -0,0 +1,118 @@ +#include "serialconsole.h" + +#include + +#include "USB.h" + +QueueHandle_t consoleCmdQueue; +TaskHandle_t consoleTaskHandle; +extern USBCDC USBSerial; + +struct consoleCommand { + uint8_t command = 0; + uint8_t len = 0; + uint8_t* data = nullptr; +}; + +void consoleStopTask() { + if (consoleTaskHandle) vTaskDelete(consoleTaskHandle); + consoleTaskHandle = NULL; +} +/* +.in>1B 5B 3C 30 3B 33 39 3B 39 4D +,in>1B 5B 3C 30 3B 33 39 3B 39 6D +,in>1B 5B 3C 32 3B 33 39 3B 39 4D +,in>1B 5B 3C 32 3B 33 39 3B 39 6D + +in>1B 5B 3C 30 3B 32 38 3B 31 32 4D +in>1B 5B 3C 30 3B 32 38 3B 31 32 6D + +in>1B 5B 3C 32 3B 32 38 3B 31 32 4D +in>1B 5B 3C 32 3B 32 38 3B 31 32 6D + +in>1B 5B 3C 36 34 3B 32 39 3B 31 32 4D +in>1B 5B 3C 36 35 3B 32 39 3B 31 32 4D +*/ + +bool escapeCommandComplete(struct consoleCommand* cmd) { + return true; +} + +void consoleUartHandler(uint8_t* data, uint8_t len) { + static struct consoleCommand* cmd = nullptr; + static bool commandStarted = false; + + while (len--) { + uint8_t usbbyte = *(data++); + + if (cmd == nullptr) { + cmd = new struct consoleCommand; + cmd->data = (uint8_t*)calloc(65, 1); + cmd->len = 0; + } + + // check if we've started a command in this byte + if ((!commandStarted) && (usbbyte == 0x1B)) { + commandStarted = true; + if (cmd->len != 0) { + BaseType_t queuestatus = xQueueSend(consoleCmdQueue, &cmd, 0); + if (queuestatus == pdFALSE) { + if (cmd->data != nullptr) free(cmd->data); + delete cmd; + } + cmd = nullptr; + } + } + + if (cmd == nullptr) { + cmd = new struct consoleCommand; + cmd->data = (uint8_t*)calloc(65, 1); + cmd->len = 0; + } + + cmd->data[cmd->len++] = usbbyte; + cmd->len %= 64; + + if (commandStarted) { + if (escapeCommandComplete(cmd) || cmd->len == 0x00) { + BaseType_t queuestatus = xQueueSend(consoleCmdQueue, &cmd, 0); + if (queuestatus == pdFALSE) { + if (cmd->data != nullptr) free(cmd->data); + delete cmd; + } + commandStarted = false; + cmd = nullptr; + } + } + } + + if (!commandStarted && cmd != nullptr) { + BaseType_t queuestatus = xQueueSend(consoleCmdQueue, &cmd, 0); + if (queuestatus == pdFALSE) { + if (cmd->data != nullptr) free(cmd->data); + delete cmd; + } + cmd = nullptr; + } +} + +void consoleTask(void* parameter) { + struct consoleCommand* cmd; + + USBSerial.print("\e[?1000;1006;1015h"); // works + + while (true) { + BaseType_t queuereceive = xQueueReceive(consoleCmdQueue, &cmd, 1500 / portTICK_PERIOD_MS); + if (queuereceive == pdTRUE) { + uint8_t c = 0; + Serial.printf("queue>"); + while (cmd->len--) { + Serial.printf(" %02X", cmd->data[c]); + c++; + } + if (cmd->data != nullptr) free(cmd->data); + delete cmd; + Serial.printf("\n"); + } + } +} diff --git a/ESP32_AP-Flasher/src/usbflasher.cpp b/ESP32_AP-Flasher/src/usbflasher.cpp index f2e6640b..96070e18 100644 --- a/ESP32_AP-Flasher/src/usbflasher.cpp +++ b/ESP32_AP-Flasher/src/usbflasher.cpp @@ -2,6 +2,7 @@ #include "USB.h" #include "powermgt.h" +#include "serialconsole.h" #include "settings.h" #include "zbs_interface.h" @@ -9,6 +10,8 @@ USBCDC USBSerial; QueueHandle_t flasherCmdQueue; +uint32_t usbConnectedStartTime = 0; + #define FLASHER_WAIT_A 0 #define FLASHER_WAIT_T 1 #define FLASHER_WAIT_CMD 2 @@ -23,6 +26,16 @@ struct flasherCommand { uint8_t* data = nullptr; }; +#define FLASHER_MODE_UNKNOWN 0 +#define FLASHER_MODE_FLASHER 1 +#define FLASHER_MODE_CONSOLE 2 +volatile uint8_t usbFlasherMode = FLASHER_MODE_UNKNOWN; + +void enterConsoleMode() { + usbFlasherMode = FLASHER_MODE_CONSOLE; + xTaskCreate(consoleTask, "consoleTask", 10000, NULL, 2, &consoleTaskHandle); +} + void sendFlasherAnswer(uint8_t answer_cmd, uint8_t* ans_buff, uint8_t len) { uint8_t* answer_buffer = (uint8_t*)calloc(2 + 2 + len + 2, 1); if (answer_buffer == nullptr) return; @@ -61,6 +74,8 @@ void flasherUartHandler(uint8_t* data, uint8_t len) { if (usbbyte == 'A') { flasherSerialState = FLASHER_WAIT_T; flasherLastCmd = millis(); + } else { + enterConsoleMode(); } break; case FLASHER_WAIT_T: @@ -105,6 +120,7 @@ void flasherUartHandler(uint8_t* data, uint8_t len) { Serial.printf("CRC failed for flasher command :( %04X\n", flasherCRC); cmd = nullptr; } else { + if (usbFlasherMode == FLASHER_MODE_UNKNOWN) usbFlasherMode = FLASHER_MODE_FLASHER; BaseType_t queuestatus = xQueueSend(flasherCmdQueue, &cmd, 0); if (queuestatus == pdFALSE) { if (cmd->data != nullptr) free(cmd->data); @@ -118,15 +134,26 @@ void flasherUartHandler(uint8_t* data, uint8_t len) { } } +void resetFlasherState() { + if (usbFlasherMode != FLASHER_MODE_UNKNOWN) { + if (usbFlasherMode == FLASHER_MODE_CONSOLE) consoleStopTask(); + Serial.print("Resetting flasher state"); + usbFlasherMode = FLASHER_MODE_UNKNOWN; + usbConnectedStartTime = millis(); + } +} + static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { if (event_base == ARDUINO_USB_EVENTS) { arduino_usb_event_data_t* data = (arduino_usb_event_data_t*)event_data; switch (event_id) { case ARDUINO_USB_STARTED_EVENT: Serial.println("USB PLUGGED"); + resetFlasherState(); break; case ARDUINO_USB_STOPPED_EVENT: Serial.println("USB UNPLUGGED"); + resetFlasherState(); break; case ARDUINO_USB_SUSPEND_EVENT: Serial.printf("USB SUSPENDED: remote_wakeup_en: %u\n", data->suspend.remote_wakeup_en); @@ -134,31 +161,40 @@ static void usbEventCallback(void* arg, esp_event_base_t event_base, int32_t eve case ARDUINO_USB_RESUME_EVENT: Serial.println("USB RESUMED"); break; - default: + ets_printf("other USB event %d\n", event_id); break; } } else if (event_base == ARDUINO_USB_CDC_EVENTS) { arduino_usb_cdc_event_data_t* data = (arduino_usb_cdc_event_data_t*)event_data; switch (event_id) { case ARDUINO_USB_CDC_CONNECTED_EVENT: - Serial.println("CDC CONNECTED"); + ets_printf("CDC CONNECTED\n"); + resetFlasherState(); + usbConnectedStartTime = millis(); break; case ARDUINO_USB_CDC_DISCONNECTED_EVENT: - Serial.println("CDC DISCONNECTED"); + ets_printf("CDC DISCONNECTED\n"); + resetFlasherState(); break; case ARDUINO_USB_CDC_LINE_STATE_EVENT: - Serial.printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts); + ets_printf("CDC LINE STATE: dtr: %u, rts: %u\n", data->line_state.dtr, data->line_state.rts); + if (data->line_state.dtr == 0) resetFlasherState(); break; case ARDUINO_USB_CDC_LINE_CODING_EVENT: - Serial.printf("CDC LINE CODING: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity); + ets_printf("CDC LINE CODING: bit_rate: %u, data_bits: %u, stop_bits: %u, parity: %u\n", data->line_coding.bit_rate, data->line_coding.data_bits, data->line_coding.stop_bits, data->line_coding.parity); + resetFlasherState(); break; case ARDUINO_USB_CDC_RX_EVENT: // Serial.printf("CDC RX [%u]:", data->rx.len); { uint8_t buf[data->rx.len]; size_t len = USBSerial.read(buf, data->rx.len); - flasherUartHandler(buf, len); + if (usbFlasherMode != FLASHER_MODE_CONSOLE) { + flasherUartHandler(buf, len); + } else { + consoleUartHandler(buf, len); + } } break; case ARDUINO_USB_CDC_RX_OVERFLOW_EVENT: @@ -226,9 +262,13 @@ void processFlasherCommand(struct flasherCommand* cmd) { if (cmd->data[0] & 2) { temp_buff[0] = zbs->begin(FLASHER_AP_SS, FLASHER_AP_CLK, FLASHER_AP_MOSI, FLASHER_AP_MISO, FLASHER_AP_RESET, FLASHER_AP_POWER, spi_speed); } else if (cmd->data[0] & 4) { + #ifdef OPENEPAPERLINK_PCB temp_buff[0] = zbs->begin(FLASHER_ALT_SS, FLASHER_ALT_CLK, FLASHER_ALT_MOSI, FLASHER_ALT_MISO, FLASHER_ALT_RESET, 255, spi_speed); + #endif } else { + #ifdef OPENEPAPERLINK_PCB temp_buff[0] = zbs->begin(FLASHER_EXT_SS, FLASHER_EXT_CLK, FLASHER_EXT_MOSI, FLASHER_EXT_MISO, FLASHER_EXT_RESET, FLASHER_EXT_POWER, spi_speed); + #endif } sendFlasherAnswer(cmd->command, temp_buff, 1); break; @@ -259,7 +299,7 @@ void processFlasherCommand(struct flasherCommand* cmd) { tempbuffer = (uint8_t*)calloc(cmd->data[0], 1); // cmd_buff[0] = len // cmd_buff[1] << 8 | cmd_buff[2] = position - //Serial.printf("Loading %d bytes from %04X \n", cmd->data[0], (cmd->data[1] << 8 | cmd->data[2])); + // Serial.printf("Loading %d bytes from %04X \n", cmd->data[0], (cmd->data[1] << 8 | cmd->data[2])); for (int i = 0; i < cmd->data[0]; i++) { tempbuffer[i] = zbs->read_flash((cmd->data[1] << 8 | cmd->data[2]) + i); } @@ -275,7 +315,7 @@ void processFlasherCommand(struct flasherCommand* cmd) { sendFlasherAnswer(cmd->command, temp_buff, 1); break; } - //Serial.printf("Writing %d bytes to %04X \n", cmd->data[0], (cmd->data[1] << 8 | cmd->data[2])); + // Serial.printf("Writing %d bytes to %04X \n", cmd->data[0], (cmd->data[1] << 8 | cmd->data[2])); for (int i = 0; i < cmd->data[0]; i++) { if (cmd->data[3 + i] != 0xff) { for (uint8_t attempts = 0; attempts < 10; attempts++) { @@ -324,13 +364,16 @@ void processFlasherCommand(struct flasherCommand* cmd) { void usbFlasherTask(void* parameter) { flasherCmdQueue = xQueueCreate(10, sizeof(struct flasherCommand*)); + consoleCmdQueue = xQueueCreate(10, sizeof(struct consoleCommand*)); #if ARDUINO_USB_MODE #warning Wrong USB mode is in use, check settings in platformio.ini #endif USB.onEvent(usbEventCallback); USBSerial.onEvent(usbEventCallback); - USBSerial.begin(); + USBSerial.setTimeout(1000); USB.begin(); + USBSerial.begin(); + struct flasherCommand* cmd; while (true) { BaseType_t queuereceive = xQueueReceive(flasherCmdQueue, &cmd, portMAX_DELAY);