I am attempting to extend the ST7735_t3 class to include some customized (albeit high SPI transaction cost) print functions. Specifically I am adding the ability to outline or fill in the background of each printed character based on a enum in the derived class. The issue is I have a switch statement that will only ever execute code from the one of the first few case statements (when it does indeed match)... all other lower statements are skipped (in spite of the case matching the switch variable). On using if statements directly below the switch statement the code executes: validating the input of the switch statement. Is this something that I need to look out for? Are the lower cases of switch statements getting optimized out? (of course I could have fat fingered something but I refactored bunch of different ways and produced a standalone .ino and .h to reproduce the issue, still got the same result... which is why I am here) I have a workaround with the if's, but I really am curious as to what is going on here. I have included code for an .ino and .h that demonstrates the issue. This was compiled with all the different optimizations attempting to figure this out (it is a bit wordy since I started explicitly casting things during debugging).
Arduino 1.8.15
Teensy 4.0 connected to a st7735
Teensy Loader 1.55
only external library is the ST7735_t3.h
tft_xtenderTest.ino
tftXtndr.h
Output of code: you should see matching
"2,This never executes..: IFFFF solidBg" statments like the
"1,Switch outline: If outline"
Arduino 1.8.15
Teensy 4.0 connected to a st7735
Teensy Loader 1.55
only external library is the ST7735_t3.h
tft_xtenderTest.ino
Code:
//tft_xtenderTest.ino
#include "tftXtndr.h"
#define TFT_MISO 12
#define TFT_MOSI 11 //a12
#define TFT_SCK 13 //a13
#define TFT_DC 9
#define TFT_CS 10
#define TFT_RST 8
static tftXtndr tft = tftXtndr(TFT_CS, TFT_DC, TFT_RST);
void setup(void) {
Serial.begin(115200);;
delay(2000); // give serial monitor time to come up
// Use this initializer if you're using a 1.8" TFT 128x160 displays
tft.initR(INITR_BLACKTAB);
tft.initR(INITR_BLACKTAB);
tft.initR(INITR_BLACKTAB);
// yes... 3 times... only way to get st7735 to (consistently) initialize
// (one time results in intermittent (1 out of 4 times) white screen of death)
tft.fillScreen(ST7735_BLACK);
tft.SetCustBackgroundColor(ST7735_BLACK);
tft.myOutColor = ST77XX_BLUE;
tft.myBgType = tftXtndr::myBackGroundTypes::outline;
tft.println("This should print with a BLUE outline .");
Serial.println();
tft.SetCustBackgroundColor(ST7735_MAGENTA);
tft.myBgType = tftXtndr::myBackGroundTypes::solidBg;
tft.println("solid: This should print with a MAGENTA solid background.");
Serial.println();
//tft.SetCustBackgroundColor(ST7735_GREEN);
tft.myOutColor = ST7735_GREEN;
tft.myBgType = tftXtndr::myBackGroundTypes::outline;
tft.println("outline: This should print with a GREEN outline background.");
Serial.println();
tft.SetCustBackgroundColor(ST77XX_BLUE);
tft.myBgType = tftXtndr::myBackGroundTypes::nada; // just for fun
tft.println("solid: This should print with a BLUE solid background.");
Serial.println();
tft.myOutColor = ST77XX_ORANGE;
tft.myBgType = tftXtndr::myBackGroundTypes::outline;
tft.println("outline: This should print with a ORANGE outline .");
Serial.println();
tft.SetCustBackgroundColor(ST77XX_ORANGE);
//tft.myOutColor = ST77XX_ORANGE;
tft.myBgType = tftXtndr::myBackGroundTypes::solidBg;
tft.setTextColor(ST77XX_RED);
tft.println("outline: This should print with a ORANGE background .");
Serial.println();
}
void loop() {
// put your main code here, to run repeatedly:
}
tftXtndr.h
Code:
// tftXtndr.h
#include "ST7735_t3.h"
class tftXtndr :
public ST7735_t3
{
public:
enum myBackGroundTypes : uint8_t
{
none = 0,
outline = 1,
solidBg = 2,
nada = 3,
};
// controller variable used to specify background type.
myBackGroundTypes myBgType = myBackGroundTypes::solidBg;
tftXtndr(uint8_t cs, uint8_t rs, uint8_t sid, uint8_t sclk, uint8_t rst) :ST7735_t3(cs, rs, sid, sclk, rst)
{
this->myTxtColor = ST77XX_WHITE;
this->myOutColor = ST77XX_BLACK;
this->myBakGndColor = ST77XX_BLACK;
this->myBgType = myBackGroundTypes::none;
}
tftXtndr(uint8_t CS, uint8_t RS, uint8_t RST = -1) :ST7735_t3(CS, RS, RST)
{
this->myTxtColor = ST77XX_WHITE;
this->myOutColor = ST77XX_BLACK;
this->myBakGndColor = ST77XX_BLACK;
this->myBgType = myBackGroundTypes::none;
}
//overriding the virtual write function of base class
size_t write(const uint8_t* buffer, size_t size);
//overriding the other virtual write function of base class
// not needed for this example.
//size_t write(uint8_t);
void SetCustBackgroundColor(uint16_t bakGrndColor);
uint16_t myTxtColor; // buffer for text color
uint16_t myOutColor; // buffer for custom outline color
uint16_t myBakGndColor; // buffer for background color
};
void tftXtndr::SetCustBackgroundColor(uint16_t bakGrndColor)
{
this->textbgcolor = bakGrndColor;
this->myBakGndColor = bakGrndColor;
}
size_t tftXtndr::write(const uint8_t* buffer, size_t size)
{
Serial.print(this->myBgType);
Serial.print(F(","));
// FOR SOME REASON THE SWITCH IS WILL NOT EXECUTE THE "solidBg" or "nada" cases
switch ((uint8_t)(tftXtndr::myBackGroundTypes)this->myBgType)
{
case (uint8_t)tftXtndr::myBackGroundTypes::outline:
Serial.print(F("Switch outline: "));
int16_t x = this->cursor_x;
int16_t y = this->cursor_y;
this->setTextColor(this->myOutColor);
if (x > 0) { this->cursor_x--; }
if (y > 0) { this->cursor_y--; }
ST7735_t3::write(buffer, size);
if (x < (this->_screenHeight - 1)) { this->cursor_x = (x + 1); }
if (y < (this->_screenHeight - 1)) { this->cursor_y = (y + 1); }
ST7735_t3::write(buffer, size);
this->cursor_x = x;
this->cursor_y = y;
this->setTextColor(this->myTxtColor);
break;
case(uint8_t)tftXtndr::myBackGroundTypes::solidBg:
Serial.print(F(" This never executes..."));
this->textbgcolor = this->myBakGndColor;
break;
case (uint8_t)tftXtndr::myBackGroundTypes::nada:
Serial.print(F("nadda This never executes..."));
this->textbgcolor = this->myBakGndColor;
break;
default:
Serial.print(F("default"));
break;
}
if (this->myBgType == (uint8_t)tftXtndr::myBackGroundTypes::solidBg)
{
Serial.print(F(" IFFFF solidBg"));
this->textbgcolor = this->myBakGndColor;
}
else if (this->myBgType == (uint8_t)tftXtndr::myBackGroundTypes::outline)
{
Serial.print(F(" IF outline: "));
int16_t x = this->cursor_x;
int16_t y = this->cursor_y;
this->setTextColor(this->myOutColor);
if (x > 0) { this->cursor_x--; }
if (y > 0) { this->cursor_y--; }
ST7735_t3::write(buffer, size);
if (x < (this->_screenHeight - 1)) { this->cursor_x = (x + 1); }
if (y < (this->_screenHeight - 1)) { this->cursor_y = (y + 1); }
ST7735_t3::write(buffer, size);
this->cursor_x = x;
this->cursor_y = y;
this->setTextColor(this->myTxtColor);
}
//this->fillRect(this->cursor_x, this->cursor_y, (6 * size), 8, ST77XX_BLUE);
return ST7735_t3::write(buffer, size);
}
Output of code: you should see matching
"2,This never executes..: IFFFF solidBg" statments like the
"1,Switch outline: If outline"
Code:
1,Switch outline: IF outline: 1,Switch outline: IF outline:
2, IFFFF solidBg2, IFFFF solidBg
1,Switch outline: IF outline: 1,Switch outline: IF outline:
3,3,
1,Switch outline: IF outline: 1,Switch outline: IF outline:
2, IFFFF solidBg2, IFFFF solidBg