From 65558360efeef290f89a9b55a272e483d2c65ff6 Mon Sep 17 00:00:00 2001 From: atc1441 Date: Tue, 20 Feb 2024 18:12:44 +0100 Subject: [PATCH] Added offline lines to TLSR FW, If the AP is not found the display will draw 5 lines to notify the user --- ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.c | 22 ++++++++++++++++-- ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.h | 1 + ARM_Tag_FW/OpenEPaperLink_TLSR/src/main.c | 12 +++++++++- .../OpenEPaperLink_TLSR/src/syncedproto.c | 6 +++-- binaries/Tag/TLSR_HS_35_ALPHA.bin | Bin 52652 -> 52816 bytes 5 files changed, 36 insertions(+), 5 deletions(-) diff --git a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.c b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.c index 97887835..c1a2e8b1 100644 --- a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.c +++ b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.c @@ -8,9 +8,19 @@ #include "screen.h" #include "epd.h" +#define LINE_BYTE_COUNTER ((SCREEN_WIDTH/8)*5)// Draw 5 lines + +RAM uint8_t onlineState = 1; +uint32_t byteCounter = 0; +void drawOnOffline(uint8_t state) +{ + onlineState = state; +} + static uint8_t mClutMap[256]; void drawImageAtAddress(uint32_t addr, uint8_t lut) { + byteCounter = 0; struct EepromImageHeader *eih = (struct EepromImageHeader *)mClutMap; eepromRead(addr, mClutMap, sizeof(struct EepromImageHeader)); switch (eih->dataType) @@ -24,7 +34,11 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) { eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256); } - EPD_Display_byte(mClutMap[c % 256]); + if (byteCounter < LINE_BYTE_COUNTER && onlineState == 0) + EPD_Display_byte(0x55); + else + EPD_Display_byte(mClutMap[c % 256]); + byteCounter++; } EPD_Display_color_change(); for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) @@ -42,7 +56,11 @@ void drawImageAtAddress(uint32_t addr, uint8_t lut) { eepromRead(addr + sizeof(struct EepromImageHeader) + c, mClutMap, 256); } - EPD_Display_byte(mClutMap[c % 256]); + if (byteCounter < LINE_BYTE_COUNTER && onlineState == 0) + EPD_Display_byte(0x55); + else + EPD_Display_byte(mClutMap[c % 256]); + byteCounter++; } EPD_Display_color_change(); for (uint32_t c = 0; c < (SCREEN_HEIGHT * (SCREEN_WIDTH / 8)); c++) diff --git a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.h b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.h index 205f4e3a..e38b1c97 100644 --- a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.h +++ b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/drawing.h @@ -4,6 +4,7 @@ #include #include +void drawOnOffline(uint8_t state); void drawImageAtAddress(uint32_t addr, uint8_t lut); #endif diff --git a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/main.c b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/main.c index 0f2467c3..71e39619 100644 --- a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/main.c +++ b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/main.c @@ -233,7 +233,9 @@ int main(void) noApShown = true; if (curImgSlot != 0xFF) { + drawOnOffline(0); drawImageFromEeprom(curImgSlot); + drawOnOffline(1); } else { @@ -248,7 +250,15 @@ int main(void) noApShown = false; our_ch = currentChannel; printf("AP Found\r\n"); - epd_display("AP Found", batteryVoltage, ownMacString, 1); + if (curImgSlot != 0xFF) + { + drawOnOffline(1); + drawImageFromEeprom(curImgSlot); + } + else + { + epd_display("AP Found", batteryVoltage, ownMacString, 1); + } scanAttempts = 0; wakeUpReason = WAKEUP_REASON_NETWORK_SCAN; initPowerSaving(INTERVAL_BASE); diff --git a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/syncedproto.c b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/syncedproto.c index d15c7e65..a0912197 100644 --- a/ARM_Tag_FW/OpenEPaperLink_TLSR/src/syncedproto.c +++ b/ARM_Tag_FW/OpenEPaperLink_TLSR/src/syncedproto.c @@ -484,7 +484,7 @@ static void getNumSlots() } static uint8_t findSlot(const uint8_t *ver) { - //return 0xFF; // remove me! This forces the tag to re-download each and every upload without checking if it's already in the eeprom somewhere + // return 0xFF; // remove me! This forces the tag to re-download each and every upload without checking if it's already in the eeprom somewhere uint32_t markerValid = EEPROM_IMG_VALID; for (uint8_t c = 0; c < imgSlots; c++) { @@ -837,6 +837,7 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) drawWithLut = avail->dataTypeArgument; wdt60s(); + drawOnOffline(1); drawImageFromEeprom(curImgSlot); return true; } @@ -851,6 +852,7 @@ bool processAvailDataInfo(struct AvailDataInfo *avail) sendXferComplete(); wdt60s(); + drawOnOffline(1); drawImageFromEeprom(curImgSlot); return true; } @@ -911,7 +913,7 @@ void test_firmware_writing() } } - _attribute_ram_code_ void write_ota_firmware_to_flash(void) +_attribute_ram_code_ void write_ota_firmware_to_flash(void) { irq_disable(); address = 0; diff --git a/binaries/Tag/TLSR_HS_35_ALPHA.bin b/binaries/Tag/TLSR_HS_35_ALPHA.bin index 9562895547ee0beb8e1d64042f905df7d99d1a85..a1ab0bf8ead0df2cbd7413d714b6591532b78430 100644 GIT binary patch delta 8027 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 delta 7924 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