Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Nic Limper
2023-04-24 18:54:49 +02:00
120 changed files with 12963 additions and 208 deletions

View File

@@ -5,6 +5,7 @@ struct espBlockRequest {
uint8_t checksum;
uint64_t ver;
uint8_t blockId;
uint8_t src[8];
} __packed;
struct espXferComplete {

View File

@@ -0,0 +1,8 @@
#include <Arduino.h>
extern QueueHandle_t consoleCmdQueue;
extern TaskHandle_t consoleTaskHandle;
void consoleStopTask();
void consoleTask(void* parameter);
void consoleUartHandler(uint8_t* data, uint8_t len);

View File

@@ -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

View File

@@ -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 =
+<*>-<usbflasher.cpp>-<serialconsole.cpp>
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 =
+<*>-<usbflasher.cpp>
+<*>-<usbflasher.cpp>-<serialconsole.cpp>
; ----------------------------------------------------------------------------------------
; !!! 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 =
+<*>-<usbflasher.cpp>
+<*>-<usbflasher.cpp>-<serialconsole.cpp>

View File

@@ -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,7 +81,7 @@ 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;
@@ -155,7 +156,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 {
@@ -207,8 +208,7 @@ void drawNew(uint8_t mac[8], bool buttonPressed, tagRecord *&taginfo) {
taginfo->nextupdate = now + 300;
}
break;
}
}
taginfo->modeConfigJson = doc.as<String>();
}
@@ -219,7 +219,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);
@@ -250,21 +250,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);
@@ -288,7 +286,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) {
@@ -304,7 +301,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) {
@@ -349,8 +345,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();
@@ -358,9 +356,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<String>() + "&longitude=" + doc["results"][0]["longitude"].as<String>() + "&current_weather=true&windspeed_unit=ms&timezone=" + doc["results"][0]["timezone"].as<String>());
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;
@@ -382,12 +380,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";
@@ -396,10 +394,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");
@@ -432,7 +429,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);
@@ -540,7 +536,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: "));
@@ -598,8 +594,8 @@ 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);
}
}
@@ -687,12 +683,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");
@@ -702,7 +698,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));
@@ -737,7 +733,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
@@ -756,7 +752,7 @@ bool getRssFeed(String &filename, String URL, String title, tagRecord *&taginfo,
int n = reader.getArticles(url, tag, rssArticleSize, 8);
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]);
}
} else if (taginfo->hwType == SOLUM_42_033) {
@@ -852,14 +848,14 @@ bool getCalFeed(String &filename, String URL, String title, tagRecord *&taginfo,
u8f.print(title);
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 (starttime<now && endtime>now) {
if (starttime < now && endtime > now) {
u8f.setFont(u8g2_font_t0_14b_tr);
u8f.setForegroundColor(PAL_WHITE);
u8f.setBackgroundColor(PAL_RED);
@@ -934,7 +930,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);
@@ -942,7 +938,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;
} else if (taginfo->hwType == SOLUM_42_033) {
initSprite(spr, 400, 300);

View File

@@ -1,6 +1,6 @@
#include <Arduino.h>
#ifdef OPENEPAPERLINK_PCB
#ifdef HAS_RGB_LED
#include <FastLED.h>
#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<WS2812B, FLASHER_RGB_LED, GRB>(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

View File

@@ -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

View File

@@ -216,7 +216,8 @@ void processBlockRequest(struct espBlockRequest* br) {
char buffer[150];
sprintf(buffer, "< Block Request received for file %s block %d, len %d checksum %u\0", pd->filename.c_str(), br->blockId, len, checksum);
wsLog((String)buffer);
Serial.printf("< Block Request received for MD5 %llu, file %s block %d, len %d checksum %u\n", br->ver, pd->filename.c_str(), br->blockId, len, checksum);
Serial.printf("< Block Request received for MD5 %llu, file %s block %d, len %d checksum %u", br->ver, pd->filename.c_str(), br->blockId, len, checksum);
Serial.printf(" from mac %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n", br->src[7],br->src[6],br->src[5],br->src[4],br->src[3],br->src[2],br->src[1],br->src[0]);
}
void processXferComplete(struct espXferComplete* xfc) {

View File

@@ -32,6 +32,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()) {
@@ -69,6 +71,7 @@ bool waitCmdReply() {
return false;
break;
}
vTaskDelay(1 / portTICK_RATE_MS);
}
return false;
}
@@ -77,7 +80,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);
}
@@ -97,23 +100,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();
@@ -125,9 +128,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);
@@ -145,14 +148,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:
@@ -165,7 +168,7 @@ uint16_t version;
void Ping() {
if (!txStart()) return;
Serial1.print("VER?");
AP_SERIAL_PORT.print("VER?");
txEnd();
waitingForVersion = esp_timer_get_time();
}
@@ -231,8 +234,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);
@@ -331,7 +334,8 @@ 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);
@@ -341,17 +345,19 @@ void zbsRxTask(void* parameter) {
rampTagPower(FLASHER_AP_POWER, true);
vTaskDelay(10 / portTICK_PERIOD_MS);
digitalWrite(FLASHER_AP_RESET, HIGH);
rampTagPower(FLASHER_AP_POWER, true);
vTaskDelay(10 / portTICK_PERIOD_MS);
//}
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);

View File

@@ -0,0 +1,118 @@
#include "serialconsole.h"
#include <Arduino.h>
#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");
}
}
}

View File

@@ -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);

View File

Before

Width:  |  Height:  |  Size: 728 KiB

After

Width:  |  Height:  |  Size: 728 KiB

View File

Before

Width:  |  Height:  |  Size: 985 KiB

After

Width:  |  Height:  |  Size: 985 KiB

View File

Before

Width:  |  Height:  |  Size: 254 KiB

After

Width:  |  Height:  |  Size: 254 KiB

View File

@@ -0,0 +1,15 @@
# 3D-printed programming jig
## Jig from [ATC1441](https://github.com/atc1441)
### Version: ZBS243_Pogo_Flasher
<img width="600" alt="atc1441_jig1" src="atc1441_jig1.jpg">
<img width="600" alt="atc1441_jig2" src="atc1441_jig2.jpg">
- The Jig is printed in 3 parts, and uses the 1.3mm Pogo Pins
- The Screws to connect the main and bottom body together need to be screwed in quite hard anything from 1-3mm should work
- The body and screws are designed for the ESP32 Lolin32 Lite board
#### Also available [on Tinkercad](https://www.tinkercad.com/things/37yG0A1sEFw?sharecode=woPw-7fiiAaOwkRt-xzJYHstxwA_3Xcl5dmdgnPgwAw)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@@ -0,0 +1,15 @@
# 3D-printed programming jig (old style, no PCB required)
### Version: jig-16, jig-29 and jig-42
<img width="600" alt="jig1" src="jig1.jpg">
<img width="600" alt="jig2" src="jig2.jpg">
<img width="600" alt="jig4" src="jig3.jpg">
<img width="600" alt="jig4" src="jig4.jpg">
- This design uses 1mm pogo pins to connect to the pins on the 4.2"/2.9"/1.6" Solum ESL's. My printer doesn't have the resolution to properly do the 1mm holes in the smaller rectangle, so I use a soldering iron to coax the pins through the plastic. A 1mm drill works nicely too. Whatever works for you.
- Use small screws or some compatible glue to attach the latch to the side of the cradle
- I used hot glue to attach an arduino nano to the underside next to the exposed pogo pins. An ESP32 can also be used and has more memory to provide more features in the future, but I didn't want to waste one on this

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

Before

Width:  |  Height:  |  Size: 121 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Some files were not shown because too many files have changed in this diff Show More