Forum Rule: Always post complete source code & details to reproduce any issue!
Page 3 of 3 FirstFirst 1 2 3
Results 51 to 64 of 64

Thread: NEW: GC9A01A Display driver for Teensy 3.x and Teensy 4.x

  1. #51
    Senior Member
    Join Date
    Jan 2019
    Posts
    131
    I found this online

    Code:
    In the Adafruit_SSD1306.h file look for the lines:
    
    #define SSD1306_COMSCANINC 0xC0
    #define SSD1306_COMSCANDEC 0xC8
    
    Change these lines to say:
    
    #define SSD1306_COMSCANINC 0xC8
    #define SSD1306_COMSCANDEC 0xC0
    this supposed to flip the image on the y-Axis.

    but i'm not so experienced to know where in the teensy GC9A01A library code to set these

    @mjs513 likely to help?

    EDIT: My bad, that's for a different library!

  2. #52
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,481
    Quote Originally Posted by donperryjm View Post
    I found this online

    Code:
    In the Adafruit_SSD1306.h file look for the lines:
    
    #define SSD1306_COMSCANINC 0xC0
    #define SSD1306_COMSCANDEC 0xC8
    
    Change these lines to say:
    
    #define SSD1306_COMSCANINC 0xC8
    #define SSD1306_COMSCANDEC 0xC0
    this supposed to flip the image on the y-Axis.

    but i'm not so experienced to know where in the teensy GC9A01A library code to set these

    @mjs513 likely to help?

    EDIT: My bad, that's for a different library!
    You might want to take a look at this https://github.com/Bodmer/TFT_eSPI/issues/96. Its for the ILI9341 but use of madctl is similar. HINT: Look at about line 1337 in the .cpp file.

  3. #53
    Senior Member
    Join Date
    Jan 2019
    Posts
    131
    That helped. I added this to your case structure and it rotated it. Getting somewhere. There are some faint lines on the image but at least i'm on the right path. THanks!
    Oh, I also had to change to MADCTL_RGB format


    Code:
      case 4:
          writedata8_last(0x70 | MADCTL_RGB);
          _width = GC9A01A_TFTHEIGHT;
          _height = GC9A01A_TFTWIDTH;
          break;

  4. #54
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,481
    Quote Originally Posted by donperryjm View Post
    That helped. I added this to your case structure and it rotated it. Getting somewhere. There are some faint lines on the image but at least i'm on the right path. THanks!
    Oh, I also had to change to MADCTL_RGB format


    Code:
      case 4:
          writedata8_last(0x70 | MADCTL_RGB);
          _width = GC9A01A_TFTHEIGHT;
          _height = GC9A01A_TFTWIDTH;
          break;
    This might help as well from the GC spec sheet

    Click image for larger version. 

Name:	Capture2.PNG 
Views:	20 
Size:	81.3 KB 
ID:	29482

  5. #55
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,481
    Quote Originally Posted by donperryjm View Post
    That helped. I added this to your case structure and it rotated it. Getting somewhere. There are some faint lines on the image but at least i'm on the right path. THanks!
    Oh, I also had to change to MADCTL_RGB format


    Code:
      case 4:
          writedata8_last(0x70 | MADCTL_RGB);
          _width = GC9A01A_TFTHEIGHT;
          _height = GC9A01A_TFTWIDTH;
          break;
    Your case 4 should be:
    Code:
      case 4:
        writedata8_last(0x00 | MADCTL_MY | 0x00 | MADCTL_BGR);
        _width = GC9A01A_TFTHEIGHT;
        _height = GC9A01A_TFTWIDTH;
        break;
    Just tried it

  6. #56
    Senior Member
    Join Date
    Jan 2019
    Posts
    131
    On the 2" 240x320 LCD from waveshare that change produced garbled image.

  7. #57
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,481
    Quote Originally Posted by donperryjm View Post
    On the 2" 240x320 LCD from waveshare that change produced garbled image.
    Actually for a true mirror its should be:
    Code:
      case 4:
        writedata8_last(MADCTL_MX | MADCTL_MY | 0x00 | MADCTL_BGR);
        _width = GC9A01A_TFTHEIGHT;
        _height = GC9A01A_TFTWIDTH;
        break;
      }
    A simple test of just using tft.print() shows that its being mirrored. Case 4 is the mirror of case 0 (setRotation(0)).

    Do you have a sample sketch that shows the problem

  8. #58
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,481
    Quote Originally Posted by donperryjm View Post
    On the 2" 240x320 LCD from waveshare that change produced garbled image.
    Can you post a link to your display.

  9. #59
    Senior Member
    Join Date
    Jan 2019
    Posts
    131
    https://www.waveshare.com/wiki/2inch_LCD_Module

    My problem was i was using the round LCD all this time and once I switched to the rectangular everything was flipped and the colours were off.
    The code as I have it in "Case 4:" made it behave normal.

  10. #60
    Senior Member+ mjs513's Avatar
    Join Date
    Jul 2014
    Location
    New York
    Posts
    8,481
    Quote Originally Posted by donperryjm View Post
    https://www.waveshare.com/wiki/2inch_LCD_Module

    My problem was i was using the round LCD all this time and once I switched to the rectangular everything was flipped and the colours were off.
    The code as I have it in "Case 4:" made it behave normal.
    I hate to tell you this then why are you using the GC9A01A library!!! The link is to a display using the ST7789 display chip. You should be using the ST7780 display library! Sorry, since you posted on this thread using the GC rectangular version. Try the other library.

  11. #61
    Senior Member
    Join Date
    Jan 2019
    Posts
    131
    A little too late lol. I took a look on the current ST8880 library we have, missing a few stuff I use in the GC9A01A that was modified. I had to adjust the gamma and such and it's looking/working perfectly now. And it's fast!

  12. #62
    Thanks @mjs513 and @KurtE for this great library. I've been using it to good effect with my updated version of the Uncanny Eyes codebase(s). I've recently started taking a look to see if I can improve the rendering speed though and it turns out updateScreenAsync() consistently takes a fraction over 32ms to update a single 240x240 GC9A01A screen. That means a maximum possible frame rate of ~31 FPS. In practice I'm getting around 20-24 FPS due to the time it takes to update the framebuffer before calling updateScreenAsync(). I realise I could add double-buffering to absorb most of the rendering time, but that would still max out at 31 FPS, use a lot more memory, and not help so much with two active screens (since the rendering effort is doubled).

    I feel like I must be missing something or doing something wrong. Is there anything that can be done to speed up the screen updates/DMA times? Change some SPI settings maybe? Other drivers (e.g. https://github.com/vindar/ILI9341_T4) seem to get much higher frame rates over SPI compared to what I'm seeing.

  13. #63
    Senior Member+ KurtE's Avatar
    Join Date
    Jan 2014
    Posts
    11,165
    A lot of this simply depends on the SPI clock speed:
    The display begin method has options to change the default 30mhz.
    Code:
    #elif defined(__IMXRT1052__) || defined(__IMXRT1062__) // Teensy 4.x
    #define GC9A01A_SPICLOCK 30000000u
    #define GC9A01A_SPICLOCK_READ 2000000
    ...
      void begin(uint32_t spi_clock = GC9A01A_SPICLOCK,
                 uint32_t spi_clock_read = GC9A01A_SPICLOCK_READ);
    You can try bumping up the clock speed and see if it works or not. This often depends on the displays and the wiring and the...

    And if the two eyes are on two different SPI busses, the DMA updates should be able to be done concurrently.

    There may be other tricks that can be done as well, like trying to do continuous updates and update the top of the display's memory when it is outputting the bottom and likewise the bottom part when it is displaying the upper part...

    There may also be games that can be played where you try to only update those portions of the screen that changed. I think in some of the drivers I added some support for that, in the updateScreen usage but not in the DMA async code.

  14. #64
    Ahh, thank you! I hadn't spotted the begin() parameters. Bumping spi_clock up to 48,000,000 increased the framerate to around 30+ FPS per screen. 60,000,000 hits as high as 40+ FPS, 90,000,000 even touches on 50 FPS sometimes, though it's extremely variable as the code becomes far more CPU bound as the DMA time reduces. 100,000,000 starts showing artifacts/corruption at times. Yes the eyes are on separate SPI buses and concurrent DMA is working just fine.

    Unfortunately I render the eyes column by column because it simplifies the eyelid calculations, so chasing the raster (so to speak!) isn't really viable unless I do something like rotate the displays and render sideways. I'm going to try adding a third buffer instead so I can update that even while both DMA transfers are still underway. I'd also seen the code in the driver keeping track of min/max X/Y but hadn't realised the DMA doesn't take note of that, it's very helpful to know. Maybe it won't be too hard for me to tweak the DMA so it takes into account the minY/maxY values at least, I imagine minX/maxX probably isn't so feasible.

    Thanks for the very helpful response, it gives me plenty of things to go try.

    [edit]: I forgot to mention - I'm seeing a compiler warning when trying to delete a GC9A01A_t3n object. I'm not much of a C/C++ coder but I think this indicates a bug in the GC9A01A_t3n code?

    "Delete called on non-final 'GC9A01A_t3n' that has virtual functions but non-virtual destructor"

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •