From 0591a01c5a02b46c56c31b4314b3dc41ecca266a Mon Sep 17 00:00:00 2001 From: fatcookies Date: Thu, 16 Jan 2020 21:58:02 +0000 Subject: [PATCH] Reduced stack usage in showBootLogoIfavailable(). Introduced new function OLED::drawAreaSwapped() for drawing images where the octets are reveresed endianess in 16-bit words. --- workspace/TS100/Core/Inc/OLED.hpp | 2 ++ workspace/TS100/Core/Src/OLED.cpp | 38 +++++++++++++++++++++++++++++++ workspace/TS100/Core/Src/main.cpp | 34 ++++++++++----------------- 3 files changed, 52 insertions(+), 22 deletions(-) diff --git a/workspace/TS100/Core/Inc/OLED.hpp b/workspace/TS100/Core/Inc/OLED.hpp index 2ceacb21..381fd9f0 100644 --- a/workspace/TS100/Core/Inc/OLED.hpp +++ b/workspace/TS100/Core/Inc/OLED.hpp @@ -92,6 +92,8 @@ public: static void drawSymbol(uint8_t symbolID);//Used for drawing symbols of a predictable width static void drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t* ptr); //Draw an area, but y must be aligned on 0/8 offset + static void drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, + const uint8_t* ptr); //Draw an area, but y must be aligned on 0/8 offset static void fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t value); //Fill an area, but y must be aligned on 0/8 offset static void drawFilledRect(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1, diff --git a/workspace/TS100/Core/Src/OLED.cpp b/workspace/TS100/Core/Src/OLED.cpp index 7506dd50..ebcd880a 100644 --- a/workspace/TS100/Core/Src/OLED.cpp +++ b/workspace/TS100/Core/Src/OLED.cpp @@ -262,6 +262,44 @@ void OLED::drawArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, } } } + +// Draw an area, but y must be aligned on 0/8 offset +// For data which has octets swapped in a 16-bit word. +void OLED::drawAreaSwapped(int16_t x, int8_t y, uint8_t wide, uint8_t height, + const uint8_t *ptr) { + // Splat this from x->x+wide in two strides + if (x <= -wide) + return; // cutoffleft + if (x > 96) + return; // cutoff right + + uint8_t visibleStart = 0; + uint8_t visibleEnd = wide; + + // trimming to draw partials + if (x < 0) { + visibleStart -= x; // subtract negative value == add absolute value + } + if (x + wide > 96) { + visibleEnd = 96 - x; + } + + if (y == 0) { + // Splat first line of data + for (uint8_t xx = visibleStart; xx < visibleEnd; xx+=2) { + firstStripPtr[xx + x] = ptr[xx + 1]; + firstStripPtr[xx + x + 1] = ptr[xx]; + } + } + if (y == 8 || height == 16) { + // Splat the second line + for (uint8_t xx = visibleStart; xx < visibleEnd; xx+=2) { + secondStripPtr[x + xx] = ptr[xx + 1 + (height == 16 ? wide : 0)]; + secondStripPtr[x + xx + 1] = ptr[xx + (height == 16 ? wide : 0)]; + } + } +} + void OLED::fillArea(int16_t x, int8_t y, uint8_t wide, uint8_t height, const uint8_t value) { // Splat this from x->x+wide in two strides diff --git a/workspace/TS100/Core/Src/main.cpp b/workspace/TS100/Core/Src/main.cpp index 9bbbfec8..e59cd503 100644 --- a/workspace/TS100/Core/Src/main.cpp +++ b/workspace/TS100/Core/Src/main.cpp @@ -283,31 +283,21 @@ void startMOVTask(void const *argument __unused) { #define FLASH_LOGOADDR \ (0x8000000 | 0xF800) /*second last page of flash set aside for logo image*/ +/* The header value is (0xAA,0x55,0xF0,0x0D) but is stored in little endian 16 + * bits words on the flash */ +const uint8_t LOGO_HEADER_VALUE[] = {0x55, 0xAA, 0x0D, 0xF0}; + bool showBootLogoIfavailable() { - // check if the header is there (0xAA,0x55,0xF0,0x0D) - // If so display logo - // TODO REDUCE STACK ON THIS ONE, USE DRAWING IN THE READ LOOP - uint16_t temp[98]; + uint8_t *header = (uint8_t*) (FLASH_LOGOADDR); - for (uint8_t i = 0; i < (98); i++) { - temp[i] = *(uint16_t*) (FLASH_LOGOADDR + (i * 2)); - } - uint8_t temp8[98 * 2]; - for (uint8_t i = 0; i < 98; i++) { - temp8[i * 2] = temp[i] >> 8; - temp8[i * 2 + 1] = temp[i] & 0xFF; - } + // check if the header is correct. + for(int i = 0; i < 4; i++) { + if(header[i] != LOGO_HEADER_VALUE[i]) { + return false; + } + } - if (temp8[0] != 0xAA) - return false; - if (temp8[1] != 0x55) - return false; - if (temp8[2] != 0xF0) - return false; - if (temp8[3] != 0x0D) - return false; - - OLED::drawArea(0, 0, 96, 16, (uint8_t*) (temp8 + 4)); + OLED::drawAreaSwapped(0, 0, 96, 16, (uint8_t*) (FLASH_LOGOADDR + 4)); OLED::refresh(); return true; }