Page 2 of 3

Re: LCD

Posted: Sat Jan 23, 2021 7:18 pm
by mrburnette
ag123 wrote: Sat Jan 23, 2021 5:00 pm agree for beginners, life is easier starting with a bigger mcu e.g. in the stm32f4xx series.
...
if you are new to micro-controllers programming, that stm32f103c8 blue pill only has 20k sram and 64k flash.
the 20k sram is particularly limiting and 64k flash isn't really a lot either, but works well for 'small' apps.
...
i'm messing with a ili9341 lcd currently with the Adafruit library. struggling with various problems as well, no display, takes time to 'debug' and troubleshoot what is going on.

if you do not already have the lcd, i'd suggest to try sending the data back to your pc on the serial monitor.
...
I think that the response is a weebit misleading, at least from the old Leaflab's core (Roger's):
Using Adafruit's at-that-time github code and with DMA modifications by Victor Perez on 03/17/2015, the ILI-9341 had reasonable memory and flash footprints, IMO.
Sketch uses 26,124 bytes (21%) of program storage space. Maximum is 122,880 bytes.
Global variables use 3,456 bytes of dynamic memory.

Code: Select all

Adafruit code updated to use SPI DMA
  Compiled under Arduino 1.7.8 OS: Linux Mint 17.3 Cinnamon
    Sketch uses 26,124 bytes (21%) of program storage space. Maximum is 122,880 bytes.
    Global variables use 3,456 bytes of dynamic memory.


			OLD STM Port			non-DMA STM Port          STM DMA Port
ILI9341 Test!
Benchmark                Time (microseconds)		Time (microseconds)        Time (microseconds)
Screen fill              1,026,635			716,291                    174,901
Text                     74,910				46,087                      65,358
Lines                    702,724			400,688                    692,868
Horiz/Vert Lines         84,359				57,074                      23,342
Rectangles (outline)     54,489				36,604                      16,625
Rectangles (filled)      2,132,392			1,487,410                  371,832
Circles (filled)         344,984			220,662                    181,100
Circles (outline)        306,326			174,199                    302,904
Triangles (outline)      222,948			127,154                    219,106
Triangles (filled)       715,597			472,077                    243,512
Rounded rects (outline)  130,131			78,591                      91,564
Rounded rects (filled)   2,331,405			1,615,938                  488,708
Mesmerize, my STM32F103 adaption of Harichord for Arduino by: http://g33k.blogspot.com (orig source seems to have been removed.)

Mute sound: https://youtu.be/EQ8qvEkZam4

The Mesmerize base codebase:

Code: Select all

#include "SPI.h"
#include "./Adafruit_GFX_AS.h"
#include "./Adafruit_ILI9341_STM.h"

// Pinout for Maple Mini (// For the Adafruit shield, these are the default)
#define TFT_CS         13 // PB4                  
#define TFT_DC         12 // PA15                
#define TFT_RST        14 // PB3  

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
// If using the breakout, change pins as desired
// Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_MOSI, TFT_CLK, TFT_RST, TFT_MISO);
Adafruit_ILI9341_STM tft = Adafruit_ILI9341_STM(TFT_CS, TFT_DC, TFT_RST); // Use hardware SPI

int nFrames = 100;    // higher number, slower full-cycle annimation

void setup() {

  tft.begin();
  tft.fillScreen(ILI9341_BLACK);
}


void loop(void) {
  
 
  for (int frame=0; frame < nFrames; frame++)
  {
    HariChord(frame);
  }

  tft.fillScreen(ILI9341_BLACK);

  for (int frame=(nFrames-1); frame >= 0; frame--)
  {
    HariChord(frame);
  }

  tft.fillScreen(ILI9341_BLACK);
}

void HariChord(int frame)
{
  static boolean flipflop = true;
  flipflop = !flipflop;
  int n = 7;
  int r = frame * 120 / nFrames;    // half smaller of 240 or 320
  float rot = frame * 2*PI / nFrames;
  for (int i=0; i<(n-1); i++)
  {
    float a = rot + i * 2*PI / n;
    int x1 = 120 + cos(a) * r;    // half 240
    int y1 = 160 + sin(a) * r;    // half 320
    for (int j=i+1; j<n; j++)
    {
      a = rot + j * 2*PI / n;
      int x2 = 120 + cos(a) * r;
      int y2 = 160 + sin(a) * r;
      if ( flipflop) tft.drawLine(x1,y1, x2,y2, (long) random(65535));
      if (!flipflop) tft.drawLine(x1,y1, x2,y2, (long) random(65535));
    }
  }
}

Re: LCD

Posted: Sat Jan 23, 2021 9:43 pm
by ag123
thanks @Ray
i think i'd go back to the version of Adafruit ILI9341 lcd library ported to stm32duino libmaple core
it is actually in the libraries in roger's core
https://github.com/rogerclarkmelbourne/ ... LI9341_STM
https://github.com/rogerclarkmelbourne/ ... uit_GFX_AS

i've been struggling somewhat with making the original Adafruit ILI941 library work. I'm still not sure what is my mistakes.
I actually managed to compile original Adafruit ILI9341 library code with roger's (libmaple) core for stm32f4
and installed it on a STM32F401CC blackpill board. the bin file size is 35K kind of 'huge' but i'd guess it may be because some fonts
etc are bundled with the Adaftuit lib. the sketch is the Adafruit's graphics test.

i'm seeing some responses from across the spi interface, but the screen remains blank. i'd double check my wire connections. Interestingly the last time it failed because i used PB11 which is actually mapped to pin 0 for the lcd reset pin (libmaple stm32f103 maple mini). the codes expect a non zero pin for the reset pin. so it is solved simply by using a different pin as the reset pin.
https://sparklogic.ru/libraries-hardwar ... ssues.html
SPI return values is inconsistent, and i'm thinking it could be due to lose wires etc.

Code: Select all

ILI9341 Test!
Display Power Mode: 0x8
MADCTL Mode: 0x0
Pixel Format: 0x6
Image Format: 0x0
Self Diagnostic: 0x0
Benchmark                Time (microseconds)
Screen fill              669101
Text                     46936
...
I've looked at the codes between Adafruit original ILI9341 lib vs the ported Adfruit ILI9341 lib (in roger's core).
Adafruit's original lib has more bloat as it involved 3 levels of inheritance Adafruit_ILI9341 : Adafruit_SPITFT : Adafruit_GFX,
the ported version in roger's core has only 2 Adafruit_ILI9341_STM : Adafruit_GFX. And the original Adafruit lib caters for more
different mcus / boards rather than simply stm32. And Adafruit's original has 'software SPI' which isn't needed for stm32.

A little trouble though is that i've not tried the ported lib from roger's core with the official stm core.

i'd like to suggest @Ferro Ferido can try installing roger's core alongside and copying the libs Adafruit_ILI9341_STM and Adafruit_GFX_AS
from there and perhaps put them in the source folders so that they can be referenced. and try to use those instead with stm core.
chances are that some edits may be necessary to see that it'd hook up with SPI properly.

Re: LCD

Posted: Sun Jan 24, 2021 9:47 am
by ag123
yay did it, Adafruit original ili9341 lib graphics test

Code: Select all

ILI9341 Test!
Display Power Mode: 0x94
MADCTL Mode: 0x48
Pixel Format: 0x5
Image Format: 0x80
Self Diagnostic: 0xC0
Benchmark                Time (microseconds)
Screen fill              669104
Text                     46937
Lines                    433966
Horiz/Vert Lines         55571
Rectangles (outline)     35800
Rectangles (filled)      1388952
Circles (filled)         180056
Circles (outline)        189350
Triangles (outline)      97213
Triangles (filled)       468627
Done!
youtube:
https://youtu.be/MdySCPK6Dkw

the mistake/goof is again related to the lcd reset pin
the statement

Code: Select all

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);
^^^ missing lcd reset pin when creating the instance.
needs to read

Code: Select all

#define TFT_CS		PA4
#define TFT_RST		PB0
#define TFT_DC		PB1

#define BACKLIGHT	PB10

// Use hardware SPI (on Uno, #13, #12, #11) and the above for CS/DC
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
it is quite possible to 'optimize' the library, but that Adafruit's original repository i'd guess is commonly deemed 'upstream'
changing things likely means merging codes often and a need to maintain codes over time.
a lighter/leaner fork likely works quite a bit faster and makes smaller binaries

defining SPI_HAS_TRANSACTION did slightly better - roger's (libmaple) core, stm32f4

Code: Select all

ILI9341 Test!
Display Power Mode: 0xDE
MADCTL Mode: 0x6C
Pixel Format: 0x7
Image Format: 0xC0
Self Diagnostic: 0xE0
Benchmark                Time (microseconds)
Screen fill              476799
Text                     41574
Lines                    352653
Horiz/Vert Lines         41711
Rectangles (outline)     26464
Rectangles (filled)      990327
Circles (filled)         138760
Circles (outline)        156673
Triangles (outline)      79426
Triangles (filled)       339544
Done!

Re: LCD

Posted: Sun Jan 24, 2021 5:27 pm
by mrburnette
ag123 wrote: Sun Jan 24, 2021 9:47 am yay did it, Adafruit original ili9341 lib graphics test
...
Congrats.
I have my own private copies of the modified Adafruit .h and .cpp code that has been self-modified over time. I just copy from previous project to current project and reference as:

Code: Select all

#include "./Adafruit_GFX_AS.h"
#include "./Adafruit_ILI9341_STM.h"

By having these libraries local to the sketch, they get backed-up in every ZIP. I am NOT a fan of including code automatically from /Arduino/libraries... you will eventually get bitten by library updates.

Fact: Cypress dev system pulls all libraries into the project folder for each project and automatically creates a compressed backup folder. Harddisk space is cheap, use it.

Re: LCD

Posted: Sun Jan 24, 2021 5:47 pm
by ag123
now i'm struggling with a copy of that ('optimised') ili9341 from roger's (libmaple) core
while working along i found i need to patch up codes, instead of Adafruit_GFX_AS, i made it reference Adafruit_GFX directly
while it builds, now i get a scrambled screen :lol:

there are possibly various improvements which made the codes in
https://github.com/adafruit/Adafruit-GFX-Library
and
https://github.com/adafruit/Adafruit_ILI9341
which made codes looking rather complex. lots of nesting and jumps, and it seemed there are more functions/features
than back then. so it'd take time to figure out.

for now the Adafruit's original lib still seem a good base for those starting out. I've not tried with the official core though.
hope someone who works with the official core would post their insights with Adafruit's official lib.
my build setup with the official core is broken, hence i'm currently just working with 'rogers' (libmaple) core.

there are things to lookout for with Adafruit's lib. Adafruit GFX lib bundle a large suite of fonts. they probably looks nice.
but with each font file in the Kbytes, including even a few will blow the flash budget on bluepill.
what i did is to copy:

Code: Select all

Adafruit_GFX.h
Adafruit_GFX.cpp
Adafruit_SPITFT.h
Adafruit_SPITFT.cpp
Adafruit_SPITFT_Macros.h
Adafruit_ILI9341.h
Adafruit_ILI9341.cpp
glcdfont.c
gfxfont.h
graphicstest.ino
into the sketch folder change the paths references as necessary and build
also needed are

Code: Select all

SPI.h
SPI.cpp
the spi api files need to come from the core be it official stm or roger's (libmaple)
hope that could help with making smaller binaries, it is still large nevertheless. but as my f401cc pill has 256k flash there is room for it to live there.

Re: LCD

Posted: Sun Jan 24, 2021 6:17 pm
by mrburnette
3 projects from my orig forum tests, years back with encapsulated Adafruit libs.

Re: LCD

Posted: Sun Jan 24, 2021 8:45 pm
by fredbox
Ray's advice to store local copies of the libraries with each project is sound. I've had a couple of projects unexpectedly fail to compile after a 3rd party library was automatically updated. Now I always copy any needed libraries into the project folder.

Re: LCD

Posted: Mon Jan 25, 2021 9:15 am
by ag123
ok after struggling much with the copy of Adafruit_ILI9341_STM lib from roger's core here is an 'optimised' version.
the codes didn't work 'out-of-box' i get scrambled screens etc from the beginning.

After working though it this is the result, youtube:
https://youtu.be/XAkh2IPh1lw
it is fast enough that the eye can't see some of the transitions :lol:

Code: Select all

ILI9341 Test!
Display Power Mode: 0xDE
MADCTL Mode: 0x6C
Pixel Format: 0x7
Image Format: 0xDE
Self Diagnostic: 0xE0
Benchmark                Time (microseconds)
Screen fill              153347
Text                     47856
Lines                    370174
Horiz/Vert Lines         18653
Rectangles (outline)     15786
Rectangles (filled)      320166
Circles (filled)         215450
Circles (outline)        87550
Triangles (outline)      132607
Triangles (filled)       241877
Done!
This should be considered alpha software, i.e. it barely works. on stm32f401ccu black pil rogers (libmaple) f4 core
This is based off a current snapshot of Adafruit GFX. no longer use Adafruit_GFX_AS.
SPI.h and SPI.cpp is from the core & the f4 core itself - credits goes to stevestrong
the main optimizations are SPI transactions and DMA (using the dmaSend() api)
the optimization target is only the Adafruit graphics test

a peeve about the nice Adafruit original ILI9341 lib is the codes is hard to read :lol:
this is kind of cleaner with less of the 'if-defs' but it probably won't work in all contexts.
binary size reduced to 38K bytes. a copy of the binary (for stm32f401ccu black pill) is included in the zip

pins used are:

Code: Select all

#define TFT_CS		PA4
#define TFT_CLK		PA5
#define TFT_MISO	PA6
#define TFT_MOSI	PA7
#define TFT_RST		PB0
#define TFT_DC		PB1

#define BACKLIGHT	PB10
this requires a key press on the serial monitor to start the graphics test.
pressing 's' pause at the current test
:)

Re: LCD

Posted: Mon Jan 25, 2021 2:56 pm
by mrburnette
Just for comparison...
ESP32 dev board with two (2) stock ILI9341 displays, both driven by hardware SPI
Dual-ILI9341.JPG
Dual-ILI9341.JPG (56.93 KiB) Viewed 20321 times

Code: Select all

// VSPI (default under Arduino)
SPIClass  SPI1(VSPI);
Adafruit_ILI9341 tft0=Adafruit_ILI9341(&SPI1, VSP_DC, VSP_CS, VSP_RST);

// HSPI 
SPIClass  SPI2(HSPI);
Adafruit_ILI9341 tft1=Adafruit_ILI9341(&SPI2, HSP_DC, HSP_CS, HSP_RST);
https://www.youtube.com/watch?v=N6jjls4LVwc

Code: Select all

DUAL HW SPI - ILI9341


Benchmark Disp:0/1         Time (microseconds)
Screen fill              390486	combined
Lines                    536399	combined
Horiz/Vert Lines         35202	combined
Rectangles (outline)     23250	combined
Rectangles (filled)      405623	405633
Circles (filled)         76625	76638
Circles (outline)        118033	118024
Triangles (outline)      58785	58795
Triangles (filled)       154240	154202
Rounded rects (outline)  42624	42671
Rounded rects (filled)   412597	412603
Done!

Re: LCD

Posted: Mon Jan 25, 2021 3:58 pm
by ag123
a little update to my 'optimised' version
Adafruit GFX calls fillRect() to draw those blocky fonts. However, as i filled my line buffer with 320 pixels (1 row) of data, this makes it slower when drawing the fonts. Hence i've edited codes in fillRect() to fill the line buffer with the actual pixels needed max 320 a full line.

Code: Select all

Benchmark                Time (microseconds)
Screen fill              153325
Text                     39902
Lines                    373230
Horiz/Vert Lines         18702
Rectangles (outline)     15859
Rectangles (filled)      320455
Circles (filled)         217171
Circles (outline)        87552
Triangles (outline)      133753
Triangles (filled)       243314
Done!
that got me a 1672 microseconds lead over Adafruit original, and a 7954 microseconds lead over my previous for the Text benchmark.
But some other numbers looks bloated a little more. no other codes is changed and i'm unsure why :lol:

the updated source and binary attached

edit:
those trying out this lib, can you try it on the core you used (e.g. libmaple (roger's) for stm32f1, stm core) and different board e.g. stm32f103?
this and that 2 comments above are the same except that this is more optimised for the fillRect() function.
this lib used the Arduino SPI api
https://www.arduino.cc/en/reference/SPI
and the only stm32duno libmaple specific one is dmaSend() function. if this works well i'd setup a repository on github for it

i took a look at the official core api
https://github.com/stm32duino/wiki/wiki/API#spi
i'm likely to update this again to use the same / similar api ( e.g. transfer() ) between the cores hopefully so that this can be used for both cores
oops it seemed i'd need to use some ifdef :lol:

in the mean time for those using the official stm core, u'd need to edit the codes in Adafruit_ILI9341_STM.cpp try using

Code: Select all

void transfer(_cs, lineBuffer, count, 0);
stm core
in place of

Code: Select all

dmaSend(lineBuffer, count, 0);
libmaple (roger's)