Jump to content

Paul Christopher

  • Content Count

  • Joined

  • Last visited

About Paul Christopher

  • Rank

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. Thanks Joel, the demo "demos\modules\gos\threads" works fine on my ESP32 which uses FreeRTOS. Using "Bare Metal" and my own setjmp replacement, it crashes on the ESP8266. The example does not work on Arduino Uno and Mega with "Bare Metal" either. So I am thinking about a replacement/enhancement for the threading in gos_arduino.c (without the setjmp solution in gos_x_threads). There are quite some generic Arduino threading libraries out there, but I haven't found one, that supports yield() within the threads. The all built on the principle that there is a central scheduler that regularily calls the threads (which are non-blocking and could for example be marked as 'paused'). Do you know some code that implements a cooperative scheduler supporting yield() without using setjmp and longjmp? I.e. a scheduler that simply relies on the completion of function calls? Or is this a mission impossible and I would be caught in infinte loops and race conditions? If the solution is not that efficient, I wouldn't care since real programmers who care about efficiency would not use the Arduino IDE. But I have simply no idea how to design a scheduler supporting yield without setjmp. By reinventing the wheel, I also might overlook some established principles. Any idea where to find some basic patterns for this cooperative scheduler?
  2. Thank you, inmarket and Joel! I have now implemented the fillrect function used in the Adafruit library as GDISP_HARDWARE_FILLS, and indeed, it is much faster now. All in all, I'm quite happy with the performance: Clearing the screen with a certain color takes 33ms on the ESP32 using SPI. I had some trouble getting µGFX work with the ESP8266. I have found a solution now by adding a custom setjmp/longjmp. Filling the screen just with a certain color works, but I doubt that for this the ugfx scheduler / ugfx multi-threading solution is used? What would be a good example in the code base to test whether multithreading / scheduling really works with my patch? Is this the time for me now to dive into GWIN? Or for what is the ugfx scheduler actually used?
  3. See zip file attached: Based on the tinyscreen example \ugfx\boards\base\ArduinoTinyScreen you can find now a version for an ILI9341 display and ESP32 on Arduino IDE. The ReadMe.txt explains the installation. ArduinoIDE_ESP32_ILI9341.zip
  4. Thank you Joel for the helpful explanations! I have now digged more into the code and learned a lot. With GDISP_HARDWARE_STREAM_WRITE, the µGFX driver already implements the approach I pointed out above and which is used in the Adafruit library. And I also had a look into the datasheet: The ILI9341 chip seems not to support GDISP_HARDWARE_FILLS (but for example GDISP_HARDWARE_SCROLL). My conclusion is, that the bad performance is caused by a) the need to write a wrapper around the Adafruit class, b) no way to speed up the run time by inlining the wrapper functions and c) some remaining inefficencies in the library itself (e.g. like testing on each write whether software or hardware SPI is used, although I only use hardware SPI). But the more changes I make to the library, the more difficult it gets to keep the board file in sync with the ongoing development process on https://github.com/adafruit/Adafruit_ILI9341 . So the great flexibility of the board file has a price: Performance. But for beginners like me, I think the generic board file is a nice starter for µGFX in Arduino since it works out of the box with different boards. To put it short: There is no need to write a board file. All in all: If you want to have performance, a) you won't program using the Arduino IDE, b) you will write a MCU specific board file avoiding all the extra calls / evaluations done by the library. By the way: I had some trouble making the library work with the ESP32, see and Attached you can find the updated version of the board file, tested so far on Arduino Uno, Mega 2560, ESP32. I'm going to test it also with ESP8266. Maybe I will also try to write an ESP32 specific board file to boost performance (avoiding wrappers, unnecessary calls and evaluations). Generally speaking, I think I have learned two things so far: 1) You need computing power and fast SPI to have good graphical output. Arduino Uno/Mega are far too slow for that (and have too little memory) . ESP32 is better but maybe even too slow? 2) Low-level functions such as spi.write are time critical. It is not a good idea to mess around here with much flexibility (like I tried with my generic board file) ArduinoILI9341.zip
  5. Hi inmarket and thank you for the quick reply. See http://esp-idf.readthedocs.io/en/latest/api-guides/freertos-smp.html . The ESP32 (based on a Tensilica Xtensa LX6 processor) seems to really run a FreeRTOS based operating system. I will further test this and report the results here. Otherwise there seems to be no way to run µGFX on the ESP32 since there is no setjmp available (which is also considered incompatible with the freertos approach). Or do I miss something?
  6. See https://community.ugfx.io/topic/921-errors-into-compile-ili9341-driver-for-arduino/?tab=comments#comment-6704 and for the sake of documentation for other users: If you want to run µGFX on an ESP32 and Arduino IDE, you need to enable as OS "FreeRTOS" and not "Arduino": #define GFX_USE_OS_FREERTOS TRUE #define GFX_OS_NO_INIT TRUE You might get a compiler error that "FreeRTOSConfig.h" cannot be found. Something seems to be wrong with the include paths, see https://github.com/espressif/arduino-esp32/issues/1423 In "gos_freertos.h", change the includes as follows: #include "freertos/FreeRTOS.h" #include "freertos/FreeRTOSConfig.h" #include "freertos/semphr.h" #include "freertos/task.h" Then it should compile.
  7. See https://forum.arduino.cc/index.php?topic=473378.0 . I had quite some trouble getting a cheap Chinese ILI9341 based display work with µGFX, ESP32 on Arduino IDE. The code compiled fine, the program ran fine, but I only got a white screen. No startup logo, no drawings, just a white screen. It took me quite some time to figure this out: For some of these cheap displays, its seems to be crucial to get a proper hardware reset in the beginning. Otherwise they won't output anything. To make it work, I had to change µGFX core, i. e. gdisp_lld_ILI9341.c. I replaced the given code in gdisp_lld_init for the hardware reset // Hardware reset setpin_reset(g, TRUE); gfxSleepMilliseconds(20); setpin_reset(g, FALSE); gfxSleepMilliseconds(20); with this piece of apparently well tested code from the adafruit_ili9341 library https://github.com/adafruit/Adafruit_ILI9341/blob/master/Adafruit_ILI9341.cpp#L326 : // Hardware reset setpin_reset(g, TRUE); delay(100); setpin_reset(g, FALSE); delay(100); setpin_reset(g, TRUE); delay(200); All in all, this might raise some fundamental design issue for driver and board files, since resetting the display seems to be display/board specific -- although the driver / display chip might be the same. Or to put it in other words: Wouldn't it be better, that the board file exposes a simple "void hardware_reset (void)" function which is just called from the driver's gdisp_lld_init function (instead of doing the pin toggling with the MCU / board dependent delays in the driver)?
  8. The newbie made a major mistake since he didn't know the difference between "software SPI" and "hardware SPI" and instantiated the Adafruit_ILI9341 class with software SPI by default. I changed this now, see updated zip file attached. I'm just wondering about the performance: Drawing a blue solid rectangle all over the screen takes the original Adafruit GFX library 270ms, µGFX with my Adafruit based board file 512ms. Am I doing something wrong? Is there a way to speed this up? The original Adafruit library seems to have special functions for drawing a rectangle (with no equivalent in µGFX -- sorry for the silly newbie questions?). void Adafruit_ILI9341::fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) { startWrite(); writeFillRect(x,y,w,h,color); endWrite(); } void Adafruit_ILI9341::writeFillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color){ if((x >= _width) || (y >= _height)) return; int16_t x2 = x + w - 1, y2 = y + h - 1; if((x2 < 0) || (y2 < 0)) return; // Clip left/top if(x < 0) { x = 0; w = x2 + 1; } if(y < 0) { y = 0; h = y2 + 1; } // Clip right/bottom if(x2 >= _width) w = _width - x; if(y2 >= _height) h = _height - y; int32_t len = (int32_t)w * h; setAddrWindow(x, y, w, h); writeColor(color, len); } void Adafruit_ILI9341::setAddrWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { uint32_t xa = ((uint32_t)x << 16) | (x+w-1); uint32_t ya = ((uint32_t)y << 16) | (y+h-1); writeCommand(ILI9341_CASET); // Column addr set SPI_WRITE32(xa); writeCommand(ILI9341_PASET); // Row addr set SPI_WRITE32(ya); writeCommand(ILI9341_RAMWR); // write to RAM } void Adafruit_ILI9341::writePixel(uint16_t color){ SPI_WRITE16(color); } For drawing the rectangle, I use gdispFillArea(10, 10, width-10, height - 10, Blue). In Adafruit GFX, I use tft.fillRect(10, 10, width-10, height-10, ILI9341_BLUE); The latter seems to be much faster. But I didn't know how to implement the setAddrWindow stuff in my board file. ArduinoILI9341.zip
  9. Thank you Joel and inmarket for the hints! I have implemented the multiple display support now in the board file. Attached you can find a working version of a more generic board file for the Arduino IDE based on the Adafruit_ILI9341 library which supports severals boards. I have successfully tested the board file with "Arduino Uno" and "Arduino Mega 2560". I doesn't work with the ESP32 so far (and presumably ESP8266) -- although the Adafruit library supports them. Reason: No implementation for setjmp.h in the Arduino environment, see https://community.ugfx.io/topic/921-errors-into-compile-ili9341-driver-for-arduino/?tab=comments#comment-6704 In contrast to the ESP8266, the ESP32 (with 2 cores) is however based on FreeRTOS. I tried to enable FreeRTOS for the ESP32, but with no success so far. All in all, I ran in this well-known issue with the "duplicate const" when compiling, see https://community.ugfx.io/topic/778-ads7843-board-file-for-arduino/?tab=comments#comment-5870 Having changed "gdriver.h", the board file compiled just fine. You can find a detailed explanation how to setup the Arduino project in readme.txt in the attached zip. The example is based on ugfx/boards/base/ArduinoTinyScreen. ArduinoILI9341.zip
  10. Thanks, Joel! Your hints helped me to isolate the problem, and the code compiles now. I will test the new board file this weekend when I have more time. By the way: How to deal with the initialization of multiple displays of the same kind in the board file? To be more generic (so that the user does not need to change the board file itself when using my library), I use #defines in main.c / the main .ino file to pass the pin-setting to the board file, i.e. init_board picks those #defines up and communicates with the board via the mentioned pins. But what happens if I want to use two displays of the same kind? Is init_board called twice and does GDisplay *g contain some kind of counter/index like 0, 1 I can use? If so, I could create some kind of global configuration object and use the passed index in init_board to fetch the right settings from it and store them to g->board: uint8_t GDISP_PIN_CONFIG a[2][4] = { {0, 1, 2, 3} , // MISO, CS, CLK, CD display 0 {4, 5, 6, 7} // MISO, CS, CLK, CD display 1 }; Or do I need to keep track in init_board, how many times it has been called with a static var/counter? All in all: What is the suggested way to pass the pin settings to the board file from main.c when using two displays of the same kind? Or have I misunderstood the whole concept of drivers and board files in a way?
  11. The link to the licence as given in the source code of version 2.8 seems to be wrong /* * This file is subject to the terms of the GFX License. If a copy of * the license was not distributed with this file, you can obtain one at: * * http://ugfx.org/license.html */ http://ugfx.org/license.html does not work. Should link to https://ugfx.io/license.html??
  12. Hi, I'm trying to get started with the µGFX lib, and my first project is to write a new board file for the Arduino IDE and ILI9341 displays based on the example given in µgfx/boards/base/ArduinoTinyScreen. The basic idea of my project is to use parts of Adafruit's library "Adafruit_ILI9341", since it supports a wide range of boards (Arduino Mega, TEENSYDUINO, ESP8266, ESP32, Feather STM32, ...): https://github.com/adafruit/Adafruit_ILI9341. See board file attached: I have already stripped down the library and isolated the necessary parts to keep it small. I have already integrated the parts in the interface necessary for the ILI9341 driver. When init_board is called, I simply create a new instance of the Adafruit class and store it to g->board = new Adafruit_ILI9341(GDISP_PIN_CS, GDISP_PIN_DC, GDISP_PIN_MOSI, GDISP_PIN_CLK, rst, miso) so that I can work with it. By doing this, it should also work with multiple displays, I guess. The other functions such as "acquire_bus" are just wrapper functions static GFXINLINE void acquire_bus(GDisplay *g) { g->board.startWrite(); } Alas, there is an unsolved problem which keeps me from debugging the application and testing it with different boards. It is a problem related to C and C++ intermingeling: The compiler throws the error "unknown type name 'class' class Adafruit_ILI9341". I have already tried different things (extern "C"...) but is doesn't work out for me. Is there any experienced programmer who can give me hint, so that I can finish my work and donate the board file to the project? By the way: https://wiki.ugfx.io/index.php/Teensy seems to be outdated? I think the way to go is like shown in µgfx/boards/base/ArduinoTinyScreen? Maybe we can rename the wiki page in future to "Arduino IDE supported boards" and use the new generic board file based on the Adafruit library as an example project (with wiring examples for Arduino Mega and ESP32)? My next project would then be to test µGFX Studio and show an integration in Arduino projects as well (as a replacement for the Nextion displays). Espcially the ESP32 seems suitable for that since it has two cores: one core could do the display output stuff, the other core the sensor stuff. Thanks and cheers! board_ILI9341.cpp board_ILI9341.h ugfx_test.ino
  • Create New...