Have to dig down into the core libs. It's one of those Teensy idiosyncrasies. But I like Paul's products too much not to deal with it.
Oh, I just meant that it is nontrivial to do in any case, especially when you only have 320×240 display modules at hand; and not specific to Teensy at all. Making a library too general is feature creep, and since features you cannot test are likely to be buggy, it is not a good thing. It is better to keep it to what you can use and test, and extend or rewrite it later when you know more about the use cases.
I've loved Teensies since I got my first Teensy 2.0++, especially because I
can modify the core libs if I want to, but I don't
have to for typical cases, because Paul does pretty darn good libraries (and responds excellently when someone suggests an useful change). This one originated from Adafruit, but LadyAda et al. also do pretty acceptable libraries.
In this case, after a quick look at the library sources, I *think* –– I didn't even compile-check this! –– that modifying the
ILI9341_t3::setRotation()
method would make the most sense here. In
ILI9341_t3.h
, change the declaration into
Code:
void setRotation(uint8_t r, int16_t width=ILI9341_TFTWIDTH, int16_t height=ILI9341_TFTHEIGHT);
and in
ILI9341_t3.cpp
, its implementation into
Code:
void ILI9341_t3::setRotation(uint8_t m, int16_t w, int16_t h)
{
if (w < 2) w = ILI9341_TFTWIDTH;
if (h < 2) h = ILI9341_TFTHEIGHT;
rotation = m % 4; // can't be higher than 3
beginSPITransaction(_clock);
writecommand_cont(ILI9341_MADCTL);
switch (rotation) {
case 0:
writedata8_last(MADCTL_MX | MADCTL_BGR);
_width = w;
_height = h;
break;
case 1:
writedata8_last(MADCTL_MV | MADCTL_BGR);
_width = h;
_height = w;
break;
case 2:
writedata8_last(MADCTL_MY | MADCTL_BGR);
_width = w;
_height = h;
break;
case 3:
writedata8_last(MADCTL_MX | MADCTL_MY | MADCTL_MV | MADCTL_BGR);
_width = h;
_height = w;
break;
}
endSPITransaction();
cursor_x = 0;
cursor_y = 0;
}
so that immediately after calling
tft.begin();
, you also call
tft.setRotation(rotation, width, height);
to set the display orientation and size. In my opinion, this is the least intrusive change, as it allows existing code to work as-is with no behaviour change (that is,
tft.setRotation(rotation)
was and still would be equivalent to
tft.setRotation(rotation, ILI9341_TFTWIDTH, ILI9341_TFTHEIGHT);
). I would also remove the macro definitions for
WIDTH
and
HEIGHT
in
ILI9341_t3.cpp
for consistency, as they're only used in the
ILI9341_t3::ILI9341_t3()
constructor, replacing them there with
ILI9341_TFTWIDTH
and
ILI9341_TFTHEIGHT
, respectively.
The reason for this is that
ILI9341_t3.cpp
may be compiled separately from the user sketch, so the default values of the macros will always be used for the library code; any definitions by the user code are just not visible then! Fortunately, the
ILI9341_t3
object contains private
_width
and
_height
members, which are used consistently. The only exception is the constructor (which used derivative macros
WIDTH
and
HEIGHT
for some reason to assign them their default values), and the
setRotation()
, which has to use the
ILI9341_TFTWIDTH
and
ILI9341_TFTHEIGHT
macros because the previous orientation is not recorded so it is impossible to tell
which of current
_width
and
_height
is which. Passing the new width and height as parameters, with defaulting to the original values if they are not specified, is the simplest option for supporting different-sized ILI9341-based displays, and should work well even when compiled separately.
(A separate question is how to document the parameters in a way users will understand. The specified width and height with this change is according to orientation 0 or 2, not in the orientation they are setting. This is to allow the backwards-compatible defaults to work.)
I cannot in good conscience suggest that
@PaulStoffregen include such a change in the official version, because all my ILI9341-based displays are 320×240, too (BuyDisplay/EastRising 2.8" 320x240 IPS modules, to be specific), and I cannot really test the change! And such changes should
always be tested (on both 320×240 and different-sized ILI9341-based display modules), no matter how seemingly simple or obvious, before inclusion in such a widely-used library. Theory is nice and useful, but testing in practice rules.